看起來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 4.0 Datagrid中的特定單元格獲取值?
- 4. 如何獲取WPF DataGrid SelectedCellsChanged中的單元格模板datacontext?
- 5. WPF DataGrid:如何獲取單元格的綁定表達式?
- 6. WPF Datagrid讀取單元格值
- 7. WPF DataGrid Combobox
- 8. WPF Datagrid ComboBox DataBinding
- 9. 在單元格中獲取ComboBox值?
- 10. WPF - 如何從DataGridRow獲取單元格?
- 11. WPF Datagrid。獲取選定行的每個單元格的值
- 12. 如何獲取DataGrid中ComboBox的值
- 13. 獲取其他單元格的值DataGrid WPF
- 14. 如何從WPF DataGrid中讀取單元格中的值?
- 15. 如何讀取單元格值隱藏colomn在WPF Datagrid的
- 16. 白色UI自動化:獲取WPF DataGrid單元格值?
- 17. WPF DataGrid在用戶輸入時獲取單元格值
- 18. 從WPF Datagrid獲取單元格值(在vb中)
- 19. WPF datagrid單元格顏色取決於preivous單元值
- 20. WPF DataGrid - 分級色標上的顏色單元格
- 21. WPF datagrid - 編輯的單元格的值
- 22. 如何獲取具有不同單元類別的單元格
- 23. wpf datagrid行中的小計單元格
- 24. WPF:帶有blanck單元格的DataGrid
- 25. 如何獲取DataGrid單元格的字段
- 26. c#datagrid單元格提取
- 27. WPF DataGrid單元格綁定在一個父級屬性上
- 28. 如何在WPF中選擇單元格時選擇DataGrid單元格內的TextBox?
- 29. WPF Datagrid更新單元格編輯
- 30. WPF Datagrid單元格值編輯C#
你正在走向完全相同的道路,我無處可去。但既然你堅持,這是代碼: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