当底层集合的相应属性更改时,silverlight 文本框不会更新

发布于 2024-11-07 07:21:20 字数 3615 浏览 0 评论 0原文

作为一个例子,

我有两个文本框。两个文本框的文本都绑定到类名称{String fullname, String funguName};它们不是直接绑定的,而是通过转换器绑定的。

它们正在实现 INotifyChanged,绑定的 DataContext 是 ObservableCollection 以及所有其他标准内容。

该模板已绑定,因此我一行有 2 个文本框,列表框有 10 行 问题是:

当我更改文本框 1 中的全名时,我去更改绑定集合中的有趣名称。

这不会立即反映到 GUI 上。

我怎样才能实现这个目标?我不想更新整个列表框,也不想直接将其绑定到类中的另一个属性,而是通过转换器。当属性从“TOm”更改为“dick”时,不会调用转换器,即仅第一次调用转换器。接下来,每当某些属性发生更改并被

this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("FunnyName"));

调用时,都不会调用转换器。

原始代码中添加了

集合类

public class VariableData : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

String _Source;

    /// <summary>
    /// Gets or sets the source.
    /// </summary>
    /// <value>
    /// The source.
    /// </value>
    public String Source
    {
        get { return _Source; }
        set
        {
            _Source = value; if (this.PropertyChanged != null)
                this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("Source"));
        }
    }
}

绑定

<TextBox Name="textBoxFileLocation"
         Text="{Binding Converter={StaticResource mapTypeToDataConverter}, ConverterParameter=41}"
         Margin="5,5,5,5" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2">
</TextBox>

转换器

public class MapTypeToDataConverter : IValueConverter
{
    #region IValueConverter Members

    /// <summary>
    /// Modifies the source data before passing it to the target for display in the UI.
    /// </summary>
    /// <param name="value">The source data being passed to the target.</param>
    /// <param name="targetType">The <see cref="T:System.Type"/> of data expected by the target dependency property.</param>
    /// <param name="parameter">An optional parameter to be used in the converter logic.</param>
    /// <param name="culture">The culture of the conversion.</param>
    /// <returns>
    /// The value to be passed to the target dependency property.
    /// </returns>
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null)
            return "";

        VariableData cus = null;
        try
        {
            cus = (VariableData)value;
        }
        catch (Exception e3)
        {
            return null;
        }
        if (cus == null)
            return "";

        int temp = int.Parse(parameter.ToString());

        int mapType = temp / 10;
        int whatToreturn = temp % 10;

        if (mapType != cus.MappingType)
        {
            if (whatToreturn == 3)
                return false;
            else
                return "";
        }

        switch (whatToreturn)
        {
            case 1:
                return cus.Source;
                break;
            case 2:
                return cus.Query;
                break;
            case 3:
                if (cus.Source != null && cus.Source.Length > 0)
                    return true;
                else
                    return false;
        }

        return "";
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return (int)value;
    }

    #endregion IValueConverter Members
}

As an example

I have a 2 text boxes. Text of both text boxes are bound to class Name {String fullname, String funnyName}; They are not directly bound but by a converter

They are implementing INotifyChanged and the bound DataContext is ObservableCollection and all other standard stuff.

This template is bound so that I have 2 text boxes in one row and the listbox has 10 rows
THe question is :

when I change fullname in text box 1, I go and change the funnyname in the bound collection.

This is not not reflected immediately onto the GUI.

How can I achieve this? I don't want to update entire list box, and I don't want to directly bind it to another property in my class, but through a converter. The converter is not called when property changes from say "TOm" to "dick" i.e converter is only called first time. Next whenever some property changes and

this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("FunnyName"));

is called, the converter is not invoked.

have added the original code

the collection class

public class VariableData : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

String _Source;

    /// <summary>
    /// Gets or sets the source.
    /// </summary>
    /// <value>
    /// The source.
    /// </value>
    public String Source
    {
        get { return _Source; }
        set
        {
            _Source = value; if (this.PropertyChanged != null)
                this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("Source"));
        }
    }
}

the binding

<TextBox Name="textBoxFileLocation"
         Text="{Binding Converter={StaticResource mapTypeToDataConverter}, ConverterParameter=41}"
         Margin="5,5,5,5" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2">
</TextBox>

the converter

public class MapTypeToDataConverter : IValueConverter
{
    #region IValueConverter Members

    /// <summary>
    /// Modifies the source data before passing it to the target for display in the UI.
    /// </summary>
    /// <param name="value">The source data being passed to the target.</param>
    /// <param name="targetType">The <see cref="T:System.Type"/> of data expected by the target dependency property.</param>
    /// <param name="parameter">An optional parameter to be used in the converter logic.</param>
    /// <param name="culture">The culture of the conversion.</param>
    /// <returns>
    /// The value to be passed to the target dependency property.
    /// </returns>
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null)
            return "";

        VariableData cus = null;
        try
        {
            cus = (VariableData)value;
        }
        catch (Exception e3)
        {
            return null;
        }
        if (cus == null)
            return "";

        int temp = int.Parse(parameter.ToString());

        int mapType = temp / 10;
        int whatToreturn = temp % 10;

        if (mapType != cus.MappingType)
        {
            if (whatToreturn == 3)
                return false;
            else
                return "";
        }

        switch (whatToreturn)
        {
            case 1:
                return cus.Source;
                break;
            case 2:
                return cus.Query;
                break;
            case 3:
                if (cus.Source != null && cus.Source.Length > 0)
                    return true;
                else
                    return false;
        }

        return "";
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return (int)value;
    }

    #endregion IValueConverter Members
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夜清冷一曲。 2024-11-14 07:21:20

您似乎将整个 VariableData 绑定为值,然后使用转换器提取所需的输出。由于 VariableData 实例本身没有改变(您的 ConvertBack 没有返回 VariableData 类型的新对象),因此 UI 没有理由相信它需要更新其 UI。

您应该做的是删除转换器并绑定到 VariableData 的属性,将所需的逻辑移动到 VariableData 中,根据需要创建其他属性。如果更改一个属性也会影响另一个属性,您可以确保为这两个属性引发 PropertyChanged 事件。

You appear to be binding the whole VariableData as the value then using a converter to extract the output you need. Since the VariableData instance itself isn't changing (your ConvertBack is not returning a new object of type VariableData) there is no reason for the UI to believe that it needs to update its UI.

What you should do is drop the converter and bind to properties of VariableData move the logic you need into VariableData create additional properties as necessary. If changing one property affects also another you can ensure that PropertyChanged events are raised for both.

鹤舞 2024-11-14 07:21:20

您是否在 XAML 中设置了 Mode=TwoWay

<TextBox Text="{Binding MyProperty, Mode=TwoWay, Converter={StaticResource myConverter}}" />

(目前不在 IDE 中,因此可能存在拼写错误)

这意味着当 MyProperty 时 UI 会更新当 UI 更改时, 会更改,MyProperty 也会更新。

Have you set Mode=TwoWay in the XAML:

<TextBox Text="{Binding MyProperty, Mode=TwoWay, Converter={StaticResource myConverter}}" />

(not at an IDE at the moment so there might be typos)

This will mean that the UI updates when MyProperty changes as well as MyProperty updating when the UI changes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文