【问题标题】:How to bind a List<T1> or List<T2> to a UserControl.List<IInterfaceForT1AndT2>?如何将 List<T1> 或 List<T2> 绑定到 UserControl.List<IInterfaceForT1AndT2>?
【发布时间】:2016-07-12 08:09:41
【问题描述】:

我有一个接口和两个类。

public interface IFieldValue
{
  Int64 FieldId { get; set; }
  string Value { get; set; }
}

public class CarFieldValue : IFieldValue
{
  public Int64 CarId { get; set; }
  public Int64 FieldId { get; set; }
  public string Value { get; set; } 
}

public class HouseFieldValue : IFieldValue
{
  public Int64 HouseId { get; set; }
  public Int64 FieldId { get; set; }
  public string Value { get; set; } 
}

现在我有一个通用的用户控件来显示CarHouse 的字段值。用户控件绑定到相应的 ViewModel。

public class CarViewModel : INotifyPropertyChanged
{
  (...)

  private ObservableCollection<CarFieldValue> _FieldValues;
  public ObservableCollection<CarFieldValue> FieldValues
  {
    get { return _FieldValues; }
    set
    {
      if (_FieldValues!= value)
      {
        _FieldValues= value;
        SendPropertyChanged("FieldValues");
      }
    }
  }
}

public class HouseViewModel : INotifyPropertyChanged
{
  (...)

  private ObservableCollection<HouseFieldValue> _FieldValues;
  public ObservableCollection<HouseFieldValue> FieldValues
  {
    get { return _FieldValues; }
    set
    {
      if (_FieldValues!= value)
      {
        _FieldValues= value;
        SendPropertyChanged("FieldValues");
      }
    }
  }
}

用户控件部分如下所示:

public IReadOnlyList<IFieldValues> FieldValues
{
  get { return (IReadOnlyList<IFieldValues>)GetValue(FieldValuesProperty); }
  set { SetValue(FieldValuesProperty, value); }
}
public static readonly DependencyProperty FieldValuesProperty = DependencyProperty.Register("FieldValues", typeof(IReadOnlyList<IFieldValues>), typeof(FieldValuesControl), new UIPropertyMetadata(null));

绑定发生在视图中的 XAML 中,例如在汽车视图中:

<myCtrls:FieldValuesControl FieldValues="{Binding MyCarViewModel.FieldValues}" />

我在这里找到了该解决方案]1 并且到目前为止有效。但我需要编辑(添加或删除)用户控件中的项目。 当我使用 IList&lt;IFieldValues&gt; 而不是 IReadOnlyList&lt;IFieldValues&gt; 时,绑定不起作用。没有绑定错误/警告。

我也试过ICollection&lt;IFieldValues&gt;,但没有成功。 我可以按照 cmets 中的建议使用 IEnumerable&lt;IFieldValues&gt;,但我不能使用 Add() 项目,因为我无法投射 IEnumerable

如何实现这个场景?

更新 由于我没有找到更好的解决方案,我在 ViewModel 和用户控件上都使用了ObservableCollection&lt;IFieldValues&gt;。由于我的 ViewModels 对列表没有太多作用,所以它并不复杂。感谢您的帮助。

【问题讨论】:

  • 只是在黑暗中拍摄 - 您是否尝试过指定 OneWay 绑定?
  • @LordWilmore OneWay 没有帮助。
  • @Clemens:是的,IEnumerable&lt;IFieldValues&gt; does work, but I need to add/remove items in the usercontrol. I cant 将IEnumerable 转换为ListObservableCollection。抱歉,我会在问题中更清楚地说明这一点。
  • 如果需要在用户控件中添加项目,不能对专门的列表进行操作。但是,您可以将列表项的副本保存在匹配类型的单独列表中。类似List&lt;IFieldValues&gt; items = srcList.Cast&lt;IFieldValues&gt;().ToList()

标签: c# wpf data-binding


【解决方案1】:

为什么不在UserControl 中使用ObservableCollectionIEnumerable

和其他人一样:

我认为你的问题和here一样

问题在于您的DependencyProperty 注册。 Co-variance is not applicable for generic lists

另一种可能性是使用ItemCollection 类。与默认的ItemsControl 相同(参见code)。

【讨论】:

  • 使用ObservableCollection 会导致绑定错误,因为您无法将显式ObservableCollection&lt;CarFieldValues&gt; 分别绑定ObservableCollection&lt;HouseFieldValues&gt; 到通用ObservableCollection&lt;IFieldValues&gt;IEnumerableIList 也不行。只有IReadOnlyList。我还没弄清楚区别。
  • @gumo 你试过ObservableCollection&lt;object&gt;吗?
  • 使用objectObservableCollection&lt;XxxFieldValues&gt; 具有相同的绑定错误“System.Windows.Data 错误:1:无法创建默认转换器来执行类型之间的“单向”转换 'ObservableCollection1[CarFieldValue]' and 'ObservableCollection 1[Object]'。考虑使用 Binding 的 Converter 属性..."
  • @gumo 使用背后的想法意味着来自ViewModelsObservableCollection 也使用object
  • 啊,好的,现在我明白了。我想避免从对象到IFieldValues 的必要转换。我会试试ItemCollection
猜你喜欢
  • 1970-01-01
  • 2010-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-09
  • 2011-02-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多