看起来WFP DataGridComboBoxColumn对此列中的所有单元格使用单个ItemsSource。我有一种情况,ComboBox项目依赖于同一行中的其他单元格。我设法在PreparingCellForEdit事件中填充ItemsSource。但是,它不能按需要工作。最初,该列中的所有单元都是空的。一旦我为此列的ComboBox填充ItemsSource,所有相关的单元格(具有相同的项源)将显示值。但是,如果我单击另一种类型的单元格(填充了不同的项目源),则所有值都将消失,并且新类型单元格显示值。你只能使用一组Items Source作为列吗?我不敢相信这是真的。我错过了什么吗?任何解决方法?如何为WPF DataGrid获取单元格级别的ComboBox?
回答
感谢乔纳森的例子,我解决我的问题如下。我修改了乔纳森的代码来突出我的解决方案。我从他的例子中删除了Territory属性,因为我不需要它来解决我的问题。
有两列。第一列是国家。第二列是StateCandidate。 State列绑定到状态列表,StateCandidate列绑定到StateCandidates列表。关键在于StateCandidates列表在状态改变时重新创建。因此,每行中可能有不同的状态候选列表(基于所选状态)。
MainWindow.xaml
<Window x:Class="WpfTest1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid Name="Zoom" AutoGenerateColumns="False" Background="DarkGray" RowHeaderWidth="50" HeadersVisibility="All">
<DataGrid.Columns>
<DataGridTemplateColumn x:Name="colState" Header="State" Width="120">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding State}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox SelectedItem="{Binding State}" ItemsSource="{Binding States}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn x:Name="colStateCandiate" Header="State Candidate" Width="200">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding StateCandidate}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox SelectedItem="{Binding StateCandidate}" ItemsSource="{Binding StateCandidates}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
namespace WpfTest1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
List<Model> list = new List<Model>();
list.Add(new Model() { State = "TX", StateCandidate = "TX2" });
list.Add(new Model() { State = "CA" });
list.Add(new Model() { State = "NY", StateCandidate = "NY1" });
list.Add(new Model() { State = "TX" });
list.Add(new Model() { State = "AK" });
list.Add(new Model() { State = "MN" });
Zoom.ItemsSource = list;
Zoom.PreparingCellForEdit += new EventHandler<DataGridPreparingCellForEditEventArgs>(Zoom_PreparingCellForEdit);
}
void Zoom_PreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e)
{
if (e.Column == colStateCandiate)
{
DataGridCell cell = e.Column.GetCellContent(e.Row).Parent as DataGridCell;
cell.IsEnabled = (e.Row.Item as Model).StateCandidates != null;
}
}
}
public class Model : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _state;
private List<string> _states = new List<string>() { "CA", "TX", "NY", "IL", "MN", "AK" };
private string _stateCandidate;
private List<string> _stateCandidates;
public string State
{
get { return _state; }
set
{
if (_state != value)
{
_state = value;
_stateCandidate = null;
if (_state == "CA" || _state == "TX" || _state == "NY")
_stateCandidates = new List<string> { _state + "1", _state + "2" };
else
_stateCandidates = null;
OnPropertyChanged("State");
}
}
}
public List<string> States
{
get { return _states; }
}
public string StateCandidate
{
get { return _stateCandidate; }
set
{
if (_stateCandidate != value)
{
_stateCandidate = value;
OnPropertyChanged("StateCandidate");
}
}
}
public List<string> StateCandidates
{
get { return _stateCandidates; }
}
public void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
需要注意的是,当状态改变时,它不会,直到选择不同的行更新StateCandidates名单,这是一个分离的问题,我会战斗。有谁知道我可以如何强制执行?
再次感谢乔纳森的灵感。我会继续寻找更好的解决方案。
你可能无法可靠地做到这一点。网格可以重用组合框或随机创建/销毁它。
偶然我碰巧正在做一个这样的屏幕。鉴于这些...
- 网格中的每一行都绑定到Trade类型的对象。
- 每个行业都有一个国家财产
- 每个行业都有一个TerritoryCanidates财产
- 更改状态属性将导致TerritoryCanidates属性来更改
这让我到的ItemsSource绑定到TerritoryCanidates的能力属性。 DataGrid在任何情况下都会遵守。
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid Name="Zoom" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="State">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding State}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox SelectedItem="{Binding State}" ItemsSource="{Binding StateCanidates}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Territory">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Territory}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox SelectedItem="{Binding Territory}" ItemsSource="{Binding TerritoryCanidates}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
Imports System.ComponentModel
Class MainWindow
Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Dim x As New List(Of Model)
x.Add(New Model)
x.Add(New Model)
x.Add(New Model)
Zoom.ItemsSource = x
End Sub
End Class
Class Model
Implements INotifyPropertyChanged
Public ReadOnly Property StateCanidates As List(Of String)
Get
Return New List(Of String) From {"CA", "TX", "NY"}
End Get
End Property
Public ReadOnly Property TerritoryCanidates As List(Of String)
Get
If State = "" Then Return Nothing
Return New List(Of String) From {State & "1", State & "2"}
End Get
End Property
Private m_State As String
Public Property State() As String
Get
Return m_State
End Get
Set(ByVal value As String)
m_State = value
OnPropertyChanged("State")
OnPropertyChanged("TerritoryCanidates")
End Set
End Property
Private m_Territory As String
Public Property Territory() As String
Get
Return m_Territory
End Get
Set(ByVal value As String)
m_Territory = value
OnPropertyChanged("Territory")
End Set
End Property
Public Sub OnPropertyChanged(ByVal propertyName As String)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
End Class
我很困惑...它对你有用吗?我只是试了一下,不能使它工作。我试过的是这样的:我为ItemsSource绑定了一个新的集合。此集合将在另一个属性更改时重新创建。我没有看到任何组合框下拉菜单。 – newman 2010-10-02 02:42:01
奇怪的是,它看起来像内置的组合框列没有像我期望的那样工作。我重新做了我的例子,使用像我真正的程序使用的模板列。 – 2010-10-02 09:43:40
P.S.我现在正式讨厌编辑数据的DataGrid。相反,我只是使用ItemsControl。 – 2010-10-02 09:48:24
- 1. WPF Toolkit DataGrid SelectionChanged获取单元格值
- 2. WPF Datagrid单元格为空
- 3. 如何从WPF中的datagrid获取单元格的值?
- 4. 如何获取WPF DataGrid单元格的位置?
- 5. 如何从WPF 4.0 Datagrid中的特定单元格获取值?
- 6. 如何获取WPF DataGrid SelectedCellsChanged中的单元格模板datacontext?
- 7. 如何获取WPF中Datagrid的单元格数据值?
- 8. WPF DataGrid:如何获取单元格的绑定表达式?
- 9. 如何在运行时获取datagrid单元格值(C#WPF)?
- 10. datagrid获取单元格索引
- 11. 如何在WPF DataGrid中使用单元格级组合框?
- 12. WPF Datagrid读取单元格值
- 13. WPF Datagrid ComboBox DataBinding
- 14. WPF DataGrid Combobox
- 15. wpf datagrid combobox列
- 16. WPF DataGrid Combobox selectedItem
- 17. WPF禁用DataGrid单元格
- 18. WPF - 如何从DataGridRow获取单元格?
- 19. 在单元格中获取ComboBox值?
- 20. WPF Datagrid。获取选定行的每个单元格的值
- 21. 如何获取DataGrid中ComboBox的值
- 22. 如何读取单元格值隐藏colomn在WPF Datagrid的
- 23. 如何从WPF DataGrid中读取单元格中的值?
- 24. 获取其他单元格的值DataGrid WPF
- 25. WPF Datagrid获取选定的单元格值
- 26. 如何我可以在wpf中获取datagrid中的单元格的值?
- 27. 如何获取未在WPF中选择的DataGrid的单元格内容?
- 28. WPF Datagrid查找Combobox
- 29. WPF DataGrid在用户输入时获取单元格值
- 30. 从WPF Datagrid获取单元格值(在vb中)
你正在走向完全相同的道路,我无处可去。但既然你坚持,这是代码:http://www.scottlogic.co.uk/blog/colin/tag/ieditableobject/ – 2010-10-03 12:42:24
@Jonathan:非常感谢你的链接。但是,我无法为这个示例做这项工作,也许是因为我没有使用DataTable。尽管如此,我在博客中发现了一条评论,指向http://codefluff.blogspot.com/2010/05/commiting-bound-cell-changes.html。这个解决方案很好。 – newman 2010-10-03 14:09:10
我的appologies,我发布了错误的链接。我也没有使用DataTable,你的链接实际上是我最终使用的。 – 2010-10-04 05:14:41