【问题标题】:Unable to populate DataGrid无法填充数据网格
【发布时间】:2016-10-21 17:08:46
【问题描述】:

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

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

我想我真的错过了一些小事。

点击按钮不填充第二列

视图模型:

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>

【问题讨论】:

  • 你设置了VARIABLE.SimpleDict["x"] = "x";,但你没有告诉任何人。这样做时不会引发任何事件。 Dictionary 没有实现 INotifyCollectionChanged
  • 谢谢!那么,可以做哪些改变。请为我的目标建议一些可以使用的 DS/其他解决方法:我希望能够动态添加列并相应地映射到一些类似字典的结构,我可以在其中添加/修改内容。
  • 当您更改其中的值时尝试VARIABLE.NotifyPropertyChanged("SimpleDict")
  • 好的。我做了这个改变: public void ButtonBase_OnClick() { foreach (var VARIABLE in SomEmployees) { VARIABLE.SimpleDict["x"] = "x"; VARIABLE.NotifyPropertyChanged("SimpleDict"); } } 但是,不起作用。
  • 你在哪里添加tt到ColumnCollection?

标签: c# wpf mvvm data-binding datagrid


【解决方案1】:

我在这里看到两个问题。

首先是Dictionary&lt;TKey,TValue&gt; 没有实现INotifyCollectionChanged,因此当您更改其中的值时,不会引发任何事件并且UI 永远不会知道它。您可以查找 ObservableDictionary&lt;K,V&gt; 并使用它(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&lt;String, Object&gt;,这样您就可以支持更多类型而不仅仅是字符串,并将格式留给UI。我可能会考虑在SimpleDict 属性中公开ReadOnlyDictionary&lt;K,V&gt;,而可写字典是一个私有字段——因此调用者别无选择,只能使用SetColumnValue(k,v) 来设置列值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多