在 WPF 中,如果你希望 DataGrid 中的 ComboBox 选项根据同一行的另一个单元格的值而不同,可以通过绑定和数据模板来实现。以下是一个详细的示例,展示如何实现这一功能。
假设你有一个 DataGrid,其中有两列:Category
和 SubCategory
。SubCategory
列中的 ComboBox 选项应根据 Category
列的值而变化。
首先,创建一个数据模型来表示每一行的数据。
public class Item
{
public string Category { get; set; }
public string SubCategory { get; set; }
}
创建一个视图模型来管理数据和选项。
public class ViewModel
{
public ObservableCollection<Item> Items { get; set; }
public Dictionary<string, List<string>> SubCategories { get; set; }
public ViewModel()
{
Items = new ObservableCollection<Item>
{
new Item { Category = "Fruit", SubCategory = "Apple" },
new Item { Category = "Vegetable", SubCategory = "Carrot" }
};
SubCategories = new Dictionary<string, List<string>>
{
{ "Fruit", new List<string> { "Apple", "Banana", "Orange" } },
{ "Vegetable", new List<string> { "Carrot", "Broccoli", "Spinach" } }
};
}
}
创建一个数据模板选择器,用于根据 Category
列的值选择不同的 ComboBox 选项。
public class SubCategoryTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var cell = container as FrameworkElement;
if (cell != null && item != null)
{
var itemData = item as Item;
if (itemData != null)
{
var window = Application.Current.MainWindow;
var viewModel = window.DataContext as ViewModel;
if (viewModel != null && viewModel.SubCategories.ContainsKey(itemData.Category))
{
var subCategories = viewModel.SubCategories[itemData.Category];
var comboBoxTemplate = new DataTemplate();
var factory = new FrameworkElementFactory(typeof(ComboBox));
factory.SetValue(ComboBox.ItemsSourceProperty, subCategories);
factory.SetBinding(ComboBox.SelectedItemProperty, new Binding("SubCategory"));
comboBoxTemplate.VisualTree = factory;
return comboBoxTemplate;
}
}
}
return null;
}
}
在 XAML 中定义 DataGrid 和绑定视图模型。
<Window x:Class="WpfApp.MainWindow"
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"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:SubCategoryTemplateSelector x:Key="SubCategoryTemplateSelector" />
</Window.Resources>
<Grid>
<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Category" Binding="{Binding Category}" />
<DataGridTemplateColumn Header="SubCategory" CellTemplateSelector="{StaticResource SubCategoryTemplateSelector}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
在代码隐藏文件中设置 DataContext。
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
}
<Window x:Class="WpfApp.MainWindow"
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"
领取专属 10元无门槛券
手把手带您无忧上云