0

我有一个对象集合,在对象内部会有一些属性和一个动态对象列表。我是我的例子,这用 Name 和 Numbers 属性来说明。

现在我让它看起来正确,但是我在从后面的代码中更改数据时遇到了问题。如果我在 MainWindow() 内的 mList 中更改某些内容,它会正确显示在我的 DataGrid 上,但如果我在 Click 内执行相同操作,即使没有任何反应。

我看过 INotifyPropertyChanged,但这并没有改变什么。

请注意,这是我为这个问题创建的示例项目

我的列表.cs

public class MyObject : IEnumerable<object[]>
{
    public string Name { get; set; }
    public int[] Numbers { get; set; }

    public IEnumerator<object[]> GetEnumerator()
    {
        var obj = new object[Numbers.Length + 1];
        obj[0] = Name;
        for (var i = 0; i < Numbers.Length; i++)
            obj[i + 1] = Numbers[i];

        yield return obj;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

主窗口.xaml.cs

private List<MyObject> mList;
    public MainWindow()
    {
        InitializeComponent();

        mList = new List<MyObject>
                    {
                        new MyObject {Name = "List 1", Numbers = new[] {1, 2, 3, 4}},
                        new MyObject {Name = "List 2", Numbers = new[] {1, 2, 3, 4}},
                        new MyObject {Name = "List 3", Numbers = new[] {1, 2, 3, 4}}
                    };

        dataGrid.ItemsSource = mList;
        var columnNames = new[] {"List", "Number 1", "Number 2", "Number 3", "Number 4"};
        AddColumns(dataGrid, columnNames);

        mList[0].Name = "Test";   //Works
        mList[0].Numbers[0] = 123;  //Works

    }
    private void AddColumns(DataGrid gv, string[] columnNames)
    {
        for (int i = 0; i < columnNames.Length; i++)
            gv.Columns.Add(new DataGridTextColumn()
                               {
                                   Header = columnNames[i],
                                   Binding = new Binding(String.Format("[{0}]", i))
                               });

    }

    private void ButtonClick(object sender, RoutedEventArgs e)
    {
        mList[0].Name = "Test test";   //Don't work
        mList[0].Numbers[0] = 234;  //Don't work
    }
}

主窗口.xaml

<StackPanel>
    <Button Click="ButtonClick">Test</Button>
    <DataGrid Height="Auto" Name="dataGrid" AutoGenerateColumns="False"/>
</StackPanel>

编辑 这是一个已修改的 MyObject,我仍然无法从代码中更改名称

 public class MyObject : IEnumerable<object[]>, INotifyPropertyChanged
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set { _name = value;
            OnPropertyChanged("Name");
        }
    }

    public int[] Numbers { get; set; }

    public IEnumerator<object[]> GetEnumerator()
    {
        var obj = new object[Numbers.Length + 1];
        obj[0] = Name;
        for (var i = 0; i < Numbers.Length; i++)
            obj[i + 1] = Numbers[i];

        yield return obj;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}
4

2 回答 2

3

The problem is that with the following code

Binding = new Binding(String.Format("[{0}]", i))

you bind each column to a Path like [i].

For example in the case of column 0 (binding to property Name) you need

new Binding("Name")

With this code you should see your datagrid update after executing

mList[0].Name = "Test test";  

The same concept is valid for the other columns

于 2012-05-23T12:59:32.133 回答
2

your //Works just works because its in the ctor :) you need to implement INotifyPropertyChanged in your MyObject class and raise it when the Property changed.

for your Numbers Property you should take int wrapper wich implements INotifyPropertyChanged too.

于 2012-05-23T10:01:38.147 回答