wpf - 如何在 WPF/XAML MVVM 中将 ComboBoxes 的更改返回到 ObservableCollection
问题描述
我的 ViewModel 中有一个 ObservableCollection 汽车。汽车有两个属性,“Make”是一个字符串,而 Color 是一个自定义枚举。我已成功地将我的 Cars 集合绑定到 DataGrid,并且在 DataGrid 内,我有一个 Make 列和一个使用 ComboBox 的 Color 列。选定的值反映了我最初将 Car 设置为的值。用户可以从 ComboBox 中选择另一种颜色,但该选择不会更新回 ObservableCollection 中的 Car。我该怎么做呢?
我已将我的代码和 XAML 放在下面。任何帮助/指针都非常感谢!-戴夫
MainWindow(这是这个简单的演示,包括代码类和 ViewModel 类和汽车类):
using Library.EnumDefinitions;
using System;
using System.Collections.ObjectModel;
using System.Windows;
namespace TrickyBindingProblems
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainWindowVM();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
foreach (ICar car in (DataContext as MainWindowVM).Cars)
{
Console.WriteLine(car.Color.ToString()); // NO CHANGES in Colors unfortunately!
}
}
}
public class MainWindowVM
{
public MainWindowVM()
{
Cars = new ObservableCollection<ICar>();
Cars.Add(new Car(MyColor.Green, "Honda"));
Cars.Add(new Car(MyColor.Blue, "GM"));
Cars.Add(new Car());
}
public ObservableCollection<ICar> Cars { get; set; }
}
public class Car : ICar
{
public Car()
{
Color = MyColor.Red;
Make = "Ford";
}
public Car(MyColor color, string make)
{
Color = color;
Make = make;
}
public MyColor Color { get; set; }
public string Make { get; set; }
}
public interface ICar
{
MyColor Color { get; set; }
string Make { get; set; }
}
}
我的枚举类(我把它放在一个不同的项目和命名空间中以反映一个更大的项目)
namespace Library.EnumDefinitions
{
public enum MyColor
{
Red,
Blue,
Green
}
}
最后是 XAML
<Window x:Class="TrickyBindingProblems.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"
xmlns:local="clr-namespace:TrickyBindingProblems"
xmlns:enu="clr-namespace:Library.EnumDefinitions"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<ObjectDataProvider x:Key="EnumDataProvider" MethodName="GetValues"
ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="enu:MyColor" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<DataGrid Grid.Row="0" Grid.Column="1"
Margin="0"
HorizontalAlignment="Left"
AutoGenerateColumns="False"
Background="Transparent"
DataContext="{Binding}"
HeadersVisibility="Column"
ItemsSource="{Binding Cars}"
SelectedItem="{Binding SelectedItemProperty, Mode=TwoWay}"
RowBackground="Transparent"
RowHeight="30">
<DataGrid.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Setter Property="Foreground" Value="Black" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{x:Null}" />
<Setter Property="BorderBrush" Value="{x:Null}" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="FontWeight" Value="Bold" />
</Style>
</DataGrid.ColumnHeaderStyle>
<DataGrid.Columns>
<DataGridTemplateColumn Width="*" Header="Make">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock VerticalAlignment="Center"
Padding="5"
Text="{Binding Make}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Width="*" Header="Color (as ComboBox)">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Source={StaticResource EnumDataProvider}}" SelectedItem="{Binding Color, Mode=TwoWay}">
<ComboBox.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="Black" />
</Style>
</ComboBox.Resources>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<Button Grid.Row="2" Click="Button_Click">Push Me!</Button>
</Grid>
</Window>
解决方案
推荐阅读
- snakemake - 要求在snakemake 的文档中对“资源”和“线程”进行澄清
- elasticsearch - 使用 Elastic/Kibana 可视化获取 Web 应用程序中的当前活跃用户
- .htaccess - htaccess 重写到通配符子域解释
- python - 简化多个条件语句的最佳方法
- html - 即使将我的 html 文件重命名为 index.html,我也无法在 GitHub 页面上推送我的 repo,它只显示 README 文件。
- spartacus-storefront - 打开 SSR 时,登录用户的页面刷新导致白色闪烁
- rust - 急切加载关系
- javascript - 如何根据反应js中的输入隐藏表格行
- reactjs - 从 Next.js 项目中的任何地方访问 Socket.io
- haskell - Idris `foldl` 默认实现