MVVM:使用DataGrid CheckBox IsChecked属性来控制相邻的TextBox';s Text
本文关键字:TextBox Text 控制 DataGrid 使用 CheckBox IsChecked 属性 MVVM | 更新日期: 2024-10-23 12:25:19
我需要在不破坏MVVM的情况下完成以下操作(无代码隐藏/事件)。我有一个DataGrid,它有一个CheckBox列和一个TextBox列。如果复选框被选中,我想将TextBox的TextDecorations属性更改为Strikethrough。虽然编译器并不讨厌我的XAML,但它不起作用。DataGridTextBoxColumn的XAML如下:
<DataGridTextColumn Header="Item Description" Binding="{Binding Path=ItemDescription, Mode=TwoWay}" Width="175">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="TextAlignment" Value="Center" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=complete, Path=IsChecked}" Value="True">
<Setter Property="TextDecorations" Value="Strikethrough"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
因为对于ItemsSourceDataGrid中的每个元素,在运行时都会创建自己的TextBlock和CheckBox,所以不能按名称绑定到这些元素。相反,您应该将复选框的值和文本块的样式设置符都绑定到您的模型。例如,您有这样的Model和ViewModel:
型号:
public class SomeModel : INotifyPropertyChanged
{
private string textField;
private bool boolField;
public event PropertyChangedEventHandler PropertyChanged;
public string TextField
{
get { return textField; }
set
{
if (value == textField) return;
textField = value;
OnPropertyChanged();
}
}
public bool BoolField
{
get { return boolField; }
set
{
if (value.Equals(boolField)) return;
boolField = value;
OnPropertyChanged();
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
视图模型:
public class MainViewModel : INotifyPropertyChanged
{
private ObservableCollection<SomeModel> models;
public ObservableCollection<SomeModel> Models
{
get { return models; }
set
{
if (Equals(value, models)) return;
models = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
public MainViewModel()
{
Models = new ObservableCollection<SomeModel>();
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
因此,现在您可以将模型的BoolField绑定到复选框的值和文本块在视图中的样式设置符:
MainView.cs:
public partial class MainView : Window
{
public MainView()
{
InitializeComponent();
var mv = new MainViewModel
{
Models = { new SomeModel { BoolField = true, TextField = "One" }, new SomeModel { TextField = "Two" } },
};
DataContext = mv;
}
}
MainView.xaml:
<Window x:Class="WpfDataGridCols.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainView" Height="350" Width="525">
<Grid>
<DataGrid ItemsSource="{Binding Models}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding TextField}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="TextAlignment" Value="Center" />
<Style.Triggers>
<!--Pay attention on this:-->
<DataTrigger Binding="{Binding BoolField}" Value="True">
<Setter Property="TextDecorations" Value="Strikethrough"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridCheckBoxColumn Binding="{Binding BoolField}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>