无法填充DataGrid [英] Unable to populate DataGrid

查看:128
本文介绍了无法填充DataGrid的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建一个datagrid,其中动态生成列(这样做很好),但是我无法为自动更新的列(如INotifyPropertyChanged)创建绑定。



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



我觉得我真的在这里缺少一些小事。



点击按钮不会填充第二列





ViewModel:

  class DataGridAttachedPropertyViewModel {


public ObservableCollection< DataGridColumn> ColumnCollection {get;组; }
public ObservableCollection< AttachedPropertyEmployee>员工{get;组; }

public ICommand myCommand {get;组; }
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(SomEmployees中的var VARIABLE){
VARIABLE.SimpleDict [x] =x;
}
}

}

AttachedPropertyEmployee。 cs

  public class AttachedPropertyEmployee:INotifyPropertyChanged {

private Dictionary< string,string>箴言

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;组; }


public event PropertyChangedEventHandler PropertyChanged;

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

XAML: p>

 < 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 =LearnDataGridAttachedPropertyHeight =300Width =300>

<! -
放置一个datargrid和一个附加的属性,并更新列dynamincally。

- >


< StackPanel>

< DataGrid
本地:DataGridColumnsBehavior.BindableColumns ={Binding ColumnCollection}
x:Name =dgg
AutoGenerateColumns =False
ItemsSource ={Binding SomEmployees}>< / DataGrid>
< Button Content =填充Command ={Binding myCommand}>< / Button>

< / StackPanel>

解决方案

我在这里看到两个问题。



第一个是 Dictionary< TKey,TValue> 不实现 INotifyCollectionChanged ,所以当您更改其中的值时,不会引发任何事件,UI不会知道。你可以找到一个 ObservableDictionary< K,V> 并使用它(IIRC有几个实现),或者你可以快速和脏的方式: p>

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

这将通知网格 SimpleDict 已更改。



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

  this.ColumnCollection。添加(tc); 
this.ColumnCollection.Add(tt);

更多想法:



我会更加舒适地添加类似于 AttachedPropertyEmployee

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

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

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

顺便说一下,我会更改 SimpleDict to Dictionary< String,Object> 所以你可以支持更多的类型,而不仅仅是字符串,并留下格式化到UI。我可能会考虑在 SimpleDict 属性中显示一个 ReadOnlyDictionary< K,V> ,可写字典是一个私有字段 - 所以调用者别无选择,只能使用 SetColumnValue(k,v)设置列值。


I am trying to build a datagrid where columns are generated dynamically (this works fine) but I am unable to create bindings for the columns which update automatically (something like INotifyPropertyChanged).

Creating columns dynamically and want to use dictionary elements for binding which can be modified/added dynamically. No errors seen in debug output of visual studio.

I think I am really missing something minor here.

clicking button does not populate the second column

ViewModel:

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>

解决方案

I see two problems here.

The first is that Dictionary<TKey,TValue> doesn't implement INotifyCollectionChanged, so when you change values in it, no event is raised and the UI never knows about it. You could look for an ObservableDictionary<K,V> and use that (IIRC there are a few implementations around), or you can do it the quick and dirty way:

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

That will notify the grid that SimpleDict has changed.

The second problem is that in the DataGridAttachedPropertyViewModel constructor, you forgot to add tt to ColumnCollection.

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

More thoughts:

I would be more comfortable adding something like this to AttachedPropertyEmployee:

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

And use that in your loop instead:

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

Incidentally, I'd change SimpleDict to Dictionary<String, Object> so you can support more types than just string, and leave formatting to the UI. And I might consider exposing a ReadOnlyDictionary<K,V> in the SimpleDict property, with the writable dictionary a private field -- so callers would have no choice but to use SetColumnValue(k,v) to set the column values.

这篇关于无法填充DataGrid的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆