无法填充DataGrid

时间:2016-10-21 17:08:46

标签: c# wpf mvvm data-binding datagrid

我正在尝试构建一个动态生成列的数据网格(这很好用)但是我无法为自动更新的列创建绑定(类似于INotifyPropertyChanged)。

动态创建列并希望使用字典元素进行绑定,可以动态修改/添加。在Visual Studio的调试输出中没有看到错误。

我想我在这里真的很遗憾。

点击按钮不会填充第二列

clicking button does not populate anything

视图模型:

class DataGridAttachedPropertyViewModel {


    public ObservableCollection<DataGridColumn> ColumnCollection { get; set; }
    public ObservableCollection<AttachedPropertyEmployee> SomEmployees { get; set; }

    public ICommand myCommand { get; set; }
    public DataGridAttachedPropertyViewModel() {

        this.ColumnCollection = new ObservableCollection<DataGridColumn>();


        DataGridTextColumn tc = new DataGridTextColumn();
        tc.Header = "Sample Column";
        // tc.Binding = new Binding("name");
        Binding forCurrent =  new Binding("SimpleDict[f]");
        forCurrent.Mode = BindingMode.TwoWay;
        tc.Binding = forCurrent;

        DataGridTextColumn tt = new DataGridTextColumn();
        tt.Header = "Column x";
        // tc.Binding = new Binding("name");
        Binding forTheCurrent = new Binding("SimpleDict[x]");
        forTheCurrent.Mode = BindingMode.TwoWay;

        tt.Binding = forTheCurrent;

        myCommand = new DelegateCommand(ButtonBase_OnClick);

        this.ColumnCollection.Add(tc);
        this.SomEmployees = new ObservableCollection<AttachedPropertyEmployee>();
        this.SomEmployees.Add(new AttachedPropertyEmployee("Rajat","Norwalk"));

        this.SomEmployees.Add(new AttachedPropertyEmployee("Matthew", "Norwalk"));
    }

    public void ButtonBase_OnClick() {
        foreach (var VARIABLE in SomEmployees) {
            VARIABLE.SimpleDict["x"] = "x";
        }
    }

}

AttachedPropertyEmployee.cs

  public class AttachedPropertyEmployee : INotifyPropertyChanged {

    private Dictionary<string, string> dict;

    public Dictionary<string, string> SimpleDict {
        get { return this.dict; }
        set
        {
            if (this.dict != value) {
                this.dict = value;
                this.NotifyPropertyChanged("SimpleDict");
            }
        }
    }

    public AttachedPropertyEmployee(string Name, string Address) {
        this.SimpleDict = new Dictionary<string, string>();
        SimpleDict["f"] ="b";
        this.name = Name;
        this.address = Address;
    }

    public string name;
    public string address { get; set; }


    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propName) {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }
}

XAML:

<Window x:Class="LearnInteractivity.LearnDataGridAttachedProperty"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:LearnInteractivity"
    mc:Ignorable="d"
    Title="LearnDataGridAttachedProperty" Height="300" Width="300">

<!--
Put a datargrid and an attached property and update columns dynamincally. 

-->


<StackPanel>

    <DataGrid 
 local:DataGridColumnsBehavior.BindableColumns="{Binding ColumnCollection}"
        x:Name="dgg"
        AutoGenerateColumns="False" 
        ItemsSource="{Binding SomEmployees}"></DataGrid>
    <Button Content="Populate" Command="{Binding myCommand}"></Button>

</StackPanel>

1 个答案:

答案 0 :(得分:1)

我在这里看到两个问题。

第一个是Dictionary<TKey,TValue>未实现INotifyCollectionChanged,因此当您更改其中的值时,不会引发任何事件,并且UI永远不会知道它。您可以查找ObservableDictionary<K,V>并使用它(IIRC有一些实现),或者您可以快速而肮脏的方式:

public void ButtonBase_OnClick() {
    foreach (var VARIABLE in SomEmployees) {
        VARIABLE.SimpleDict["x"] = "x";
        VARIABLE.NotifyPropertyChanged("SimpleDict");
    }
}

这将通知网格SimpleDict已更改。

第二个问题是,在DataGridAttachedPropertyViewModel构造函数中,您忘记将tt添加到ColumnCollection

    this.ColumnCollection.Add(tc);
    this.ColumnCollection.Add(tt);

更多想法:

我更愿意将这样的内容添加到AttachedPropertyEmployee

public void SetColumValue(string key, string value) {
    SimpleDict[key] = value;
    NotifyPropertyChanged("SimpleDict");
}

然后在你的循环中使用它:

public void ButtonBase_OnClick() {
    foreach (var VARIABLE in SomEmployees) {
        VARIABLE.SetColumnValue("x", "x");
    }
}

顺便说一句,我将SimpleDict更改为Dictionary<String, Object>,因此您可以支持更多类型而不仅仅是字符串,并将格式保留给UI。我可能会考虑在ReadOnlyDictionary<K,V>属性中公开{​​{1}},可写字典是私有字段 - 因此调用者别无选择,只能使用SimpleDict来设置列值。