如何禁用新行的特定 DataGrid 单元格
How to disable a specific DataGid Cell of a new row
我有一个简单的 DataGrid
,其中有两列,例如
<DataGrid ItemsSource="{Binding Commands}" CanUserAddRows="True" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Value" Binding="{Binding Value}"/>
<DataGridTemplateColumn Header="Command">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding ComboItems}" SelectedValue="{Binding SelectedItem}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource ItemConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
我的目标是禁用 新行 的 ComboBox
单元格。下图显示了我的DataGrid
(绑定到两个项目的ObservableCollection
),其中禁用标记的列。
我已经尝试使用转换器来禁用 ComboBox
IsEnabled="{Binding Value, Converter={StaticResource DisableConverter}}"
但是在我在第一列中输入一个值之前,转换器不会被调用。
希望有人能帮助我!
基于此,可以在Loaded事件处理程序中实现
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var dataGridRow = FindChild(dataGrid, x =>
{
var element = x as DataGridRow;
if (element != null && element.Item == System.Windows.Data.CollectionView.NewItemPlaceholder)
return true;
else
return false;
}) as DataGridRow;
var combo = FindChild(dataGridRow, x =>
{
return x is ComboBox;
}) as ComboBox;
combo.IsEnabled = false;
}
有了这个帮手
public static DependencyObject FindChild(DependencyObject parent, Func<DependencyObject, bool> predicate)
{
if (parent == null) return null;
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
if (predicate(child))
{
return child;
}
else
{
var foundChild = FindChild(child, predicate);
if (foundChild != null)
return foundChild;
}
}
return null;
}
您可以将以下 Style
应用于 ComboBox
:
<ComboBox ItemsSource="{Binding ComboItems}" SelectedValue="{Binding SelectedItem}">
<ComboBox.Style>
<Style TargetType="ComboBox">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=DataContext,RelativeSource={RelativeSource AncestorType=DataGridRow}}"
Value="{x:Static CollectionView.NewItemPlaceholder}">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource ItemConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
我有一个简单的 DataGrid
,其中有两列,例如
<DataGrid ItemsSource="{Binding Commands}" CanUserAddRows="True" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Value" Binding="{Binding Value}"/>
<DataGridTemplateColumn Header="Command">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding ComboItems}" SelectedValue="{Binding SelectedItem}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource ItemConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
我的目标是禁用 新行 的 ComboBox
单元格。下图显示了我的DataGrid
(绑定到两个项目的ObservableCollection
),其中禁用标记的列。
我已经尝试使用转换器来禁用 ComboBox
IsEnabled="{Binding Value, Converter={StaticResource DisableConverter}}"
但是在我在第一列中输入一个值之前,转换器不会被调用。
希望有人能帮助我!
基于此
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var dataGridRow = FindChild(dataGrid, x =>
{
var element = x as DataGridRow;
if (element != null && element.Item == System.Windows.Data.CollectionView.NewItemPlaceholder)
return true;
else
return false;
}) as DataGridRow;
var combo = FindChild(dataGridRow, x =>
{
return x is ComboBox;
}) as ComboBox;
combo.IsEnabled = false;
}
有了这个帮手
public static DependencyObject FindChild(DependencyObject parent, Func<DependencyObject, bool> predicate)
{
if (parent == null) return null;
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
if (predicate(child))
{
return child;
}
else
{
var foundChild = FindChild(child, predicate);
if (foundChild != null)
return foundChild;
}
}
return null;
}
您可以将以下 Style
应用于 ComboBox
:
<ComboBox ItemsSource="{Binding ComboItems}" SelectedValue="{Binding SelectedItem}">
<ComboBox.Style>
<Style TargetType="ComboBox">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=DataContext,RelativeSource={RelativeSource AncestorType=DataGridRow}}"
Value="{x:Static CollectionView.NewItemPlaceholder}">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource ItemConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>