WPF:如何使用可编辑的动态列进行 DataGrid 绑定? [英] WPF: How to make DataGrid binding with dynamic columns editable?
问题描述
我需要将一些数据绑定到列数可变的 DataGrid.我使用以下代码使其工作:
I need to bind some data to a DataGrid with variable number of columns. I made it work using following code:
int n = 0;
foreach (string title in TitleList)
{
DataGridTextColumn col = new DataGridTextColumn();
col.Header = title;
Binding binding = new Binding(string.Format("DataList[{0}]", n++));
binding.Mode = BindingMode.TwoWay;
col.Binding = binding;
grid.Columns.Add(col);
}
DataList 声明为:
where DataList is declared as:
public ObservableCollection<double> DataList { get; set; }
和 TitleList 声明为:
and TitleList is declared as:
public ObservableCollection<string> TitleList { get; set; }
问题在于,即使我指定了 TwoWay 绑定,它也确实是单向的.当我单击单元格尝试编辑时,出现异常此视图不允许使用‘EditItem’".我是否只是错过了绑定表达式中的某些内容?
The problem is that, even though I specified TwoWay binding, it is really one-way. When I click a cell to try to edit, I got an exception "'EditItem' is not allowed for this view". Did I just miss something in the binding expression?
附言我发现了一篇来自 Deborah "使用 MVVM 在 Silverlight 应用程序中使用动态列填充 DataGrid".但是,我很难让它适用于我的案例(具体来说,我无法使标头绑定工作).即使它有效,我仍然面临着单元格样式不一致等问题.这就是为什么我想知道我是否可以让我上面的代码工作 - 稍微调整一下?
P.S. I found an article from Deborah "Populating a DataGrid with Dynamic Columns in a Silverlight Application using MVVM". However, I had hard time to make it work for my case (specifically, I can't make the header binding work). Even if it worked, I'm still facing issues like inconsistent cell styles. That's why I'm wondering if I could make my above code work - with a little tweak?
我发现了另一篇可能与我的问题有关的帖子:隐式双向绑定.看起来是否使用
I found another post which might be related to my problem: Implicit Two Way binding. It looks if you bind to a list of string to a TextBox using
<TextBox Text="{Binding}"/>
您将收到类似双向绑定需要 Path 或 XPath"的错误消息.但是这个问题可以很容易地通过使用
You will get an error like "Two-way binding requires Path or XPath". But the problem can easily be fixed by using
<TextBox Text="{Binding Path=DataContext, RelativeSource={RelativeSource Self}}"/>
或
<TextBox Text="{Binding .}"/>
如果我的问题可以用类似的方式解决,有人可以给我一个提示吗?
Can anybody give me a hint if my problem can be solved in a similar way?
推荐答案
您是否绑定到索引器?.你能告诉我们你的 DataList 属性是什么样的吗?
Do you bind to an indexer?. can you show us how your DataList Property looks like?
我不久前对索引属性做了同样的事情.
i did the same a while ago with an indexed property.
public SomeObjectWithIndexer DataList
{get; set;}
public class SomeObjectWithIndexer
{
public string this
{
get { ... }
set { ... }//<-- you need this one for TwoWay
}
}
您无法编辑属性的原因是您尝试编辑双字段".一种解决方法是使用 INotifyPropertyChanged 将您的 double 包装到一个类中.
the reason that you cant edit your Property, is that you try to edit a "double field". one workaround would be to wrap your double into a class with INotifyPropertyChanged.
public class DataListItem
{
public double MyValue { get; set;}//with OnPropertyChanged() and stuff
}
然后你可以使用一个
ObservableCollection<DataListItem>
并且您可以编辑您的值.索引是否总是相同的问题仍然存在:)
and you can edit your value. the question wether the index are always the same stay still around :)
Binding binding = new Binding(string.Format("DataList[{0}].MyValue", n++));
工作示例:只是为了显示双向工作
working example: just to show twoway is working
public class DataItem
{
public string Name { get; set; }
public ObservableCollection<DataListItem> DataList { get; set; }
public DataItem()
{
this.DataList = new ObservableCollection<DataListItem>();
}
}
双重包装:
public class DataListItem
{
private double myValue;
public double MyValue
{
get { return myValue; }
set { myValue = value; }//<-- set breakpoint here to see that edit is working
}
}
带有数据网格的用户控件
usercontrol with a datagrid
<UserControl x:Class="WpfStackoverflow.IndexCollectionDataGrid"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<DataGrid ItemsSource="{Binding MyList}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" />
<DataGridTextColumn Header="Index1" Binding="{Binding Path=DataList[0].MyValue, Mode=TwoWay}" />
<DataGridTextColumn Header="Index2" Binding="{Binding Path=DataList[1].MyValue, Mode=TwoWay}" />
</DataGrid.Columns>
</DataGrid>
</UserControl>
.cs
public partial class IndexCollectionDataGrid : UserControl
{
public IndexCollectionDataGrid()
{
InitializeComponent();
this.MyList = new ObservableCollection<DataItem>();
var m1 = new DataItem() {Name = "test1"};
m1.DataList.Add(new DataListItem() { MyValue = 10 });
m1.DataList.Add(new DataListItem() { MyValue = 20 });
var m2 = new DataItem() { Name = "test2" };
m2.DataList.Add(new DataListItem() { MyValue = 100 });
m2.DataList.Add(new DataListItem() { MyValue = 200 });
this.MyList.Add(m1);
this.MyList.Add(m2);
this.DataContext = this;
}
public ObservableCollection<DataItem> MyList { get; set; }
}
我希望你通过这个例子找到了正确的方向.
i hope you get in the right direction with this example.
这篇关于WPF:如何使用可编辑的动态列进行 DataGrid 绑定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!