Có vẻ WFP DataGridComboBoxColumn đang sử dụng một ItemsSource duy nhất cho tất cả các ô trong cột này. Tôi có một trường hợp các mục ComboBox phụ thuộc vào ô khác trong cùng một hàng. Tôi quản lý để cư trú ItemsSource trong sự kiện PreparingCellForEdit. Tuy nhiên, nó không hoạt động như mong muốn. Ban đầu, tất cả các ô trong cột này đều trống. Khi tôi điền vào ItemsSource cho ComboBox của cột này, tất cả các ô có liên quan (với cùng một nguồn mục) đều hiển thị các giá trị. Tuy nhiên, nếu tôi nhấp vào một loại ô khác (một nguồn mục khác được điền), tất cả các giá trị sẽ biến mất và các ô loại mới sẽ hiển thị các giá trị. Bạn chỉ có thể sử dụng một bộ Nguồn mục cho một cột? Tôi không thể tin nó là sự thật. Tôi đã bỏ lỡ bất cứ điều gì? Có cách giải quyết nào không?Làm thế nào để có được ComboBox cấp tế bào cho WPF DataGrid?
Trả lời
Nhờ ví dụ của Jonathan, tôi giải quyết vấn đề của tôi như sau. Tôi đã sửa đổi mã của Jonathan để làm nổi bật giải pháp của tôi. Tôi đã xóa thuộc tính Territory khỏi ví dụ của anh ấy vì tôi không cần nó vì vấn đề của tôi.
Có hai cột. Cột đầu tiên là State. Cột thứ hai là StateCandidate. Cột trạng thái được liên kết với một danh sách các trạng thái, và cột StateCandidate được liên kết với một danh sách StateCandidates. Điểm mấu chốt là danh sách StateCandidates được tạo lại khi trạng thái được thay đổi. Vì vậy, có thể có một danh sách khác nhau của StateCandidates trong mỗi hàng (dựa trên trạng thái được chọn).
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));
}
}
}
Lưu ý rằng, khi Nhà nước thay đổi, nó sẽ không cập nhật danh sách StateCandidates cho đến khi một dãy ghế khác được chọn, đó là một vấn đề riêng biệt tôi sẽ chiến đấu. Có ai biết tôi có thể ép buộc không?
Cảm ơn Jonathan một lần nữa vì cảm hứng của mình. Tôi sẽ tiếp tục tìm kiếm một giải pháp tốt hơn.
Có thể bạn không thể thực hiện điều đó một cách đáng tin cậy. Lưới có thể tái sử dụng hộp kết hợp hoặc tạo ngẫu nhiên/phá hủy nó.
Cơ hội tôi chỉ tình cờ làm việc trên màn hình thực hiện điều đó. Với những ...
- Mỗi hàng trong lưới được gắn với một đối tượng thuộc loại Thương mại.
- Mỗi Thương mại có một tài sản Nhà nước
- Mỗi Thương mại có một tài sản TerritoryCanidates
- Thay đổi sở hữu Nhà nước sẽ gây ra tài sản TerritoryCanidates thay đổi
này mang lại cho tôi khả năng để ràng buộc các ItemsSource đến TerritoryCanidates bất động sản. Mà lần lượt DataGrid sẽ tôn vinh trong mọi trường hợp.
<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
Tôi đang nhầm lẫn ... Tính năng này có phù hợp với bạn không? Tôi chỉ thử nó và không thể làm cho nó hoạt động được. Những gì tôi đã thử là như thế này: Tôi đã thực hiện một bộ sưu tập mới cho ItemsSource để liên kết. Bộ sưu tập này sẽ được tạo lại khi một thuộc tính khác thay đổi. Tôi không thấy bất cứ điều gì trong hộp thả xuống combobox. – newman
Rất tiếc, có vẻ như cột hộp tổ hợp tích hợp không hoạt động như tôi mong đợi. Tôi đã làm ví dụ của tôi bằng cách sử dụng các cột mẫu như chương trình thực sự của tôi sử dụng. –
P.S. Bây giờ tôi chính thức ghét DataGrid để chỉnh sửa dữ liệu. Tôi thay vì chỉ sử dụng một ItemsControl. –
- 1. Bắt trị tế bào nào trong DataGrid trong WPF
- 2. WPF DataGrid ComboBox gây ra InvalidOperationException
- 3. Làm thế nào để có được một tế bào DataFrid WPF để căn phải mà không làm cho khu vực lựa chọn trên một hàng mới nhỏ?
- 4. làm thế nào để có được hồ sơ graphviz có tế bào lót lên
- 5. Làm thế nào để có được văn bản tế bào dựa trên indexPath?
- 6. Làm thế nào để làm mới một DataGrid WPF?
- 7. Làm thế nào để làm cho tế bào bảng co lại theo nội dung?
- 8. làm thế nào biết nếu uitableview có một tế bào được chọn
- 9. WPF DataGrid - Làm thế nào để tự động thoát khỏi Chế độ chỉnh sửa?
- 10. WPF DataGrid: làm cách nào để dừng tự động cuộn khi một ô được nhấp?
- 11. WPF Toolkit DataGrid Multi-Select: Làm thế nào để có được SelectedItems ra?
- 12. tiêu đề cột đa cấp cho DataGrid trong WPF
- 13. Làm thế nào để tạo ComboBox như UserControl trong WPF
- 14. trong datagrid wpf làm thế nào để có được hàng trống trên đầu trang?
- 15. WPF DataGrid: Làm thế nào để bạn có được nội dung của một ô?
- 16. binding combobox để combobox khác trong WPF
- 17. Nền tế bào DataFrid WPF bằng cách sử dụng ràng buộc
- 18. Mã để kiểm tra xem một tế bào của một DataGrid hiện đang sửa
- 19. trong WPF làm thế nào để làm cho một DataGrid phù hợp với chiều cao cửa sổ
- 20. Làm thế nào để có được indexPath trong một tableview từ một hành động nút trong một tế bào?
- 21. Conditional Formatting: làm cho tế bào đầy màu sắc
- 22. làm thế nào để chuyển đổi một tế bào để chuỗi trong matlab
- 23. ScrollIntoView cho WPF DataGrid (MVVM)
- 24. Làm thế nào để buộc các tế bào excel thay đổi màu sắc EXPONENTIALLY?
- 25. Excel: Set màu nền của tế bào để giá trị rgb dữ liệu trong tế bào
- 26. Làm thế nào để Xác định tế bào hợp nhất trong một số Row
- 27. Làm thế nào để thiết lập maxlength cho combobox trong WPF?
- 28. Làm thế nào để đếm các nhóm của cùng một tế bào trong một mảng 2d?
- 29. Làm thế nào để tạo ra một tế bào excel ReadOnly bằng C#?
- 30. Làm thế nào để bọc đường trong một tế bào jtable?
Bạn đang đi xuống con đường chính xác giống như hư không tôi đã ở trên. Nhưng kể từ khi bạn nhấn mạnh, đây là mã: http://www.scottlogic.co.uk/blog/colin/tag/ieditableobject/ –
@ Jonathan: Cảm ơn bạn rất nhiều vì đã liên kết. Tuy nhiên, tôi không thể thực hiện công việc đó cho mẫu này, có thể vì tôi không sử dụng DataTable. Trong khi xáo trộn với điều đó, tôi đã tìm thấy một nhận xét trong blog đó trỏ đến http://codefluff.blogspot.com/2010/05/commiting-bound-cell-changes.html. Giải pháp này hoạt động rất tốt. – newman
Ứng dụng của tôi, tôi đã đăng liên kết sai. Tôi cũng không sử dụng DataTable, liên kết của bạn thực sự là liên kết mà tôi đã sử dụng. –