【问题标题】:Bind WPF DataGrid ItemsSource to method, IEnumerable<TableRow> GetRows(), of custom Table object?将 WPF DataGrid ItemsSource 绑定到自定义 Table 对象的方法 IEnumerable<TableRow> GetRows()?
【发布时间】:2010-12-16 21:50:05
【问题描述】:

我在 WPF 数据绑定的学习曲线上苦苦挣扎,可以举个例子。那些回答问题并链接到帮助他们“获得”WPF 数据绑定的文章的人可以获得奖励积分。

我正在尝试将自定义 Table 对象与 WPF DataGrid 绑定。

这是我的对象(我无法更改它们,签名被截断了一点):

public class MyTable
{
    public int ColumnCount { get; }
    public string GetColumnName(int columnIndex);
    public IEnumerable<MyTableRow> GetRows();
}

public class MyTableRow
{
    public MyTableCell [] Cells { get; }
}

public class MyTableCell
{
    public string Value { get; }
}

所以当前Window 上的DataContextMyTable 的一个实例。我看不到任何明确的方法可以从我的 MyTable 对象自动生成列,所以我在代码中生成了它们:

private void dg_Table_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    MyTable tbl = e.NewValue as MyTable;

    if (tbl != null)
    {
        //setup data grid columns
        dg_Table.Columns.Clear();

        for (int i = 0; i < tbl.ColumnCount; i++)
        {
            var column = new DataGridTextColumn()
            {
                Header = tbl.GetColumnName(i),
                Binding = new Binding(string.Format("Cells[{0}]", i))
            };

            dg_Table.Columns.Add(column);
        }
        //end setup data grid columns
    }
}

我认为下一步是将DataGridItemsSource 属性绑定到MyTable 对象上的GetRows 方法,但我不知道该怎么做。我想也许这可以使用 ObjectDataProvider 资源来完成,但我不知道如何引用 DataContext 对象上的方法。

有人可以帮我解决这个场景的 XAML 和代码吗?

【问题讨论】:

    标签: c# .net wpf data-binding


    【解决方案1】:

    AFAIK 你不能绑定到特定实例的方法。您可以绑定到在 XAML 中创建的实例的属性或方法,或静态方法,但不能绑定到给定实例的方法。

    Bind to a method in WPF

    这里有一些对我有帮助的绑定链接。

    编辑:我意识到我可能也应该尝试解决您当前的问题。 :P

    首先,我对 WPF 中的 DataGrid 控件没有太多经验。说了这么多,绑定ItemsSource的时候不是自动生成列吗?

    我处理您的问题的方法是围绕 MyTable 对象创建一个包装器,并在该包装器中实现一个调用 GetRows 方法的属性。将 DataContext 设置为包装器并将 ItemsSource 绑定到属性。

    【讨论】:

    • 奇怪的是,您不能绑定到不是通过 XAML 创建的对象上的方法的返回值。
    【解决方案2】:

    使用值转换器来索引 Cells 数组非常容易。转换器的参数是索引:

      ...
        var column = new DataGridTextColumn()
        {
          Header = tbl.GetColumnName(i),
          Binding = new Binding
          {
            Converter = CellAccessConverter.Instance,
            Parameter = i
          }
        }
      ...
    

    这是转换器本身:

      private class CellAccessConverter : IValueConverter
      {
        public static readonly Instance = new CellAccessConverter();
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
          return ((MyTableRow)value).Cells[(int)parameter];
        }
        object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
          throw new NotImplementedException();
        }
      }
    

    享受吧!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-23
      • 2011-12-17
      • 2023-03-07
      • 2011-07-10
      • 2012-02-23
      • 2011-08-23
      • 2020-01-30
      • 1970-01-01
      相关资源
      最近更新 更多