這種類型的問題真的是Model-View-ViewModel (MVVM) pattern存在的原因。
使用MVVM,您可以綁定到查看具有支持視圖所需的確切屬性的模型。這允許模型更關心需要持續保存的數據。
因此,對於你的問題,你需要創建一個LineViewModel
,這將是這個樣子:
public class LineViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool _isAutoScale;
private double _scale;
public bool IsAutoScale
{
get { return _isAutoScale; }
set
{
if (value == _isAutoScale) return;
_isAutoScale = value;
OnPropertyChange("IsAutoScale");
OnPropertyChange("IsReadOnly");
}
}
public double Scale
{
get { return _scale; }
set
{
if (value == _scale) return;
_scale = value;
OnPropertyChange("Scale");
}
}
public bool IsReadOnly => !IsAutoScale;
private void OnPropertyChange(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
同時,你也想創建一個名爲MainWindowViewModel
父視圖模型(或東西對你的情況有意義)。這裏是一個非常粗糙的版本:
public class MainWindowViewModel : INotifyPropertyChanged
{
private List<LineViewModel> _lineViewModels;
public event PropertyChangedEventHandler PropertyChanged;
public List<LineViewModel> LineViewModels
{
get { return _lineViewModels; }
set
{
if (value == _lineViewModels) return;
_lineViewModels = value;
OnPropertyChange("LineViewModels");
}
}
public MainWindowViewModel()
{
LineViewModels = new[]
{
new { AutoScale = false, Scale = 0.2 },
new { AutoScale = true, Scale = 0.3 },
new { AutoScale = false, Scale = 0.4 },
}
.Select(
x => new LineViewModel
{
IsAutoScale = x.AutoScale,
Scale = x.Scale
})
.ToList();
}
private void OnPropertyChange(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
最後,你會更新你的XAML文件看起來是這樣的:
<Window x:Class="Sandbox.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:sandbox="clr-namespace:Sandbox"
mc:Ignorable="d"
Title="MainWindow"
Height="350"
Width="525">
<Window.DataContext>
<sandbox:MainWindowViewModel />
</Window.DataContext>
<DataGrid ItemsSource="{Binding LineViewModels}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
AutoGenerateColumns="False"
CanUserAddRows="False"
CanUserDeleteRows="False"
SelectionMode="Single">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Auto Scale">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox HorizontalAlignment="Center"
IsChecked="{Binding IsAutoScale}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="Auto Scale">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Scale}"
IsReadOnly="{Binding IsReadOnly}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Window>
所以,基本上,爲MainWindow
視圖邏輯由MainWindowViewModel
和確定DataGrid
的每一行的查看邏輯由LineViewModel
控制。
請注意,許多用於實現INotifyPropertyChanged
的樣板可以使用庫/ NuGet包(如MVVM Light Toolkit和PropertyChanged.Fody)進行簡化。
你想禁用整列或相鄰單元? –
好點。答案將是相鄰的單元格。想想看,問題可能比我想象的更復雜。 –
最簡單的解決方案是將AutoScale屬性綁定到Scale列的單元格樣式的IsEnable屬性。請看我的答案,我已經給出了依賴於UI和數據依賴的答案。 –