【问题标题】:My databinding with value converter does not work我与值转换器的数据绑定不起作用
【发布时间】:2010-11-06 03:18:53
【问题描述】:

我有一个简单的 Item-class,看起来像这样:

public class Item : DependencyObject
{
    public int No
    {
        get { return (int)GetValue(NoProperty); }
        set { SetValue(NoProperty, value); }
    }

    public string Name
    {
        get { return (string)GetValue(NameProperty); }
        set { SetValue(NameProperty, value); }
    }

    public static readonly DependencyProperty NoProperty = DependencyProperty.Register("No", typeof(int), typeof(Item));
    public static readonly DependencyProperty NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(Item));
}

还有一个 ValueConverter,看起来像这样:

[ValueConversion(typeof(Item), typeof(string))]
internal class ItemToStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
        {
            return null;
        }

        var item = ((Item)value);

        var sb = new StringBuilder();
        sb.AppendFormat("Item # {0}", item.No);

        if (string.IsNullOrEmpty(item.Name) == false)
        {
            sb.AppendFormat(" - [{0}]", item.Name);
        }

        return sb.ToString();
    }


    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

在我的 WPF 窗口中,我声明了一个 DependencyProperty(称为 Items),它包含一个 Item 对象列表(List),并使用此 XAML 代码创建一个绑定到此 DependencyProperty 的 ComboBox:

<ComboBox ItemsSource="{Binding ElementName=mainWindow, Path=Items}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Converter={StaticResource itemToStringConverter}}"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

如果我执行一次下面的代码,数据绑定工作正常,但是如果我再次执行它,值转换会失败:

var item1 = new Item {Name = "Item A", No = 1};
var item2 = new Item {Name = "Item B", No = 2};
var item3 = new Item {Name = "Item C", No = 3};
Items = new List<Item> {item1, item2, item3};

问题是,ItemToStringConverter.Convert 方法现在传递一个字符串对象作为第一个参数,而不是一个项目对象?

我做错了什么?

问候, 肯尼斯

【问题讨论】:

    标签: wpf data-binding combobox textblock valueconverter


    【解决方案1】:

    简单的解决方法是检查传递给 ValueConverter 的类型。改变 Convert 方法如下:

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
            var item = value as Item;
            if(item == null) { return null; }
            var sb = new StringBuilder();
            sb.AppendFormat("Item # {0}", item.No);
            if(string.IsNullOrEmpty(item.Name) == false) {
                sb.AppendFormat(" - [{0}]", item.Name);
            }
            return sb.ToString();
        }
    

    【讨论】:

    • 这正是我到目前为止所做的,但我真的很想知道,为什么使用字符串值调用转换方法:)
    【解决方案2】:

    替代方法,

    1. 您可以从 Object 而不是 DependencyObject 派生您的类
    2. 可以实现 INotifyPropertyChange 接口
    3. 当 No 或 Name 发生任何变化时,您可以实现只读属性并触发通知事件。

    公共类项目:System.ComponentModel.INotifyPropertyChanged {

    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
    
    
    private void Notify(string p)
    {
        if (PropertyChanged != null)
            PropertyChanged(this,
                new System.ComponentModel.PropertyChangedEventArgs(p));
    }
    
    private int _No = 0;
    public int No
    {
        get
        {
            return _No;
        }
        set
        {
            _No = value;
            Notify("No");
            Notify("DisplayName");
        }
    }
    
    
    private string _Name = "";
    public string Name
    {
        get
        {
            return _Name;
        }
        set
        {
            _Name = value;
            Notify("Name");
            Notify("DisplayName");
        }
    }
    
    public string DisplayName
    {
        get
        {
            string sb = string.Format("Item # {0}", _No);
            if (!string.IsNullOrEmpty(_Name))
                sb += _Name;
            return sb;
        }
    }
    

    }

    现在您只能绑定“DisplayName”属性而不是转换器..

    1. 转换器的实现相当复杂
    2. 而基于 DependencyObject 的类只能用于 UI 目的

    【讨论】:

    • 我的示例从我的原始代码中得到了很大的简化,而我实际上从 BusinessBase 派生的 Item 类(我正在使用 CSLA.NET)。但是,添加 DisplayName 属性是个好主意。但是我还是想不通,为什么我的转换器是用字符串值调用的?
    【解决方案3】:

    如果您想使用数据绑定,您应该将您的集合分配给 ItemsSource,而不是 Items。我认为这可能会解决这个问题。

    【讨论】:

    • 我想我已经做到了,不是吗? ComboBox 的 ItemsSource 属性绑定了 Items-property...如果我错了,请纠正我。
    • 天啊!错过了 - 我认为这是您分配的 ListBox 的项目,而不是您的对象。我的错。
    猜你喜欢
    • 2018-03-26
    • 1970-01-01
    • 2011-04-16
    • 2017-11-09
    • 2015-12-03
    • 2012-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多