如何避免WPF DataGrid的NewItemPlaceholder行显示空集合提示按钮
如何避免WPF DataGrid的NewItemPlaceholder行显示空集合提示按钮
嘿,这个问题我之前也碰到过,其实核心就是要区分正常的数据行和DataGrid自动生成的那个新增行占位符(NewItemPlaceholder),然后让按钮在占位符行上隐藏掉就行。给你几个可行的方案,你可以根据自己的情况选:
方案一:用DataTrigger直接判断行类型(推荐,不用改转换器)
这个方法最直观,不用修改你现有的转换器,直接在Button的Style里加个DataTrigger,检查当前所在的DataGridRow是不是新增行(IsNewItem属性为True),是的话就把按钮设为隐藏:
<DataTemplate> <StackPanel> <Button Command="..." Visibility="{Binding Items.Count, Converter={StaticResource ConverterIntToVisibility}}"> <Button.Style> <Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}"> <Style.Triggers> <!-- 判断当前行是否为新增占位符行 --> <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=DataGridRow}, Path=IsNewItem}" Value="True"> <Setter Property="Visibility" Value="Collapsed"/> </DataTrigger> </Style.Triggers> </Style> </Button.Style> </Button> </StackPanel> </DataTemplate>
原理很简单:DataGrid的新增占位符行的IsNewItem属性会被设为True,我们通过RelativeSource找到父级的DataGridRow,判断这个属性,一旦匹配就强制隐藏按钮,优先级会高于原来的绑定值。
方案二:在转换器里判断行类型
如果你想把逻辑集中在转换器里,可以修改绑定,把当前的DataGridRow作为参数传给转换器,然后在Convert方法里判断是否为新增行:
第一步:修改XAML绑定
<Button Command="..." Visibility="{Binding Items.Count, Converter={StaticResource ConverterIntToVisibility}, ConverterParameter={Binding RelativeSource={RelativeSource AncestorType=DataGridRow}}}" />
第二步:更新转换器逻辑
public class ConverterIntToVisibility : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { // 先判断是否为新增占位符行 var dataGridRow = parameter as DataGridRow; if (dataGridRow != null && dataGridRow.IsNewItem) { return Visibility.Collapsed; } // 原来的转换逻辑 if (value is int count) { return count == 0 ? Visibility.Visible : Visibility.Collapsed; } return Visibility.Collapsed; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
这个方案适合你需要在转换器里整合更多逻辑的场景,比如除了判断行类型,还要处理其他条件。
方案三:通过DataContext判断是否为有效数据行
如果你的NewItemPlaceholder行的DataContext不是正常的ItemViewModel(比如是DataGrid内部的占位对象),也可以通过判断DataContext的类型来隐藏按钮:
第一步:修改XAML绑定
<Button Command="..." Visibility="{Binding Items.Count, Converter={StaticResource ConverterIntToVisibility}, ConverterParameter={Binding}}" />
第二步:更新转换器逻辑
public class ConverterIntToVisibility : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { // 判断当前DataContext是否为有效的ItemViewModel if (!(parameter is ItemViewModel)) { return Visibility.Collapsed; } // 原来的转换逻辑 if (value is int count) { return count == 0 ? Visibility.Visible : Visibility.Collapsed; } return Visibility.Collapsed; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
这个方案的前提是,NewItemPlaceholder行的DataContext不是ItemViewModel类型——如果你的DataGrid是自动创建新的ItemViewModel作为新增行的上下文,那这个方法可能不适用,这时候方案一或二更靠谱。
内容来源于stack exchange
相关产品推荐
相关产品推荐

