当且仅当它位于 ListView 的最后一个 ListViewItem(行)中时,才折叠 WPF 按钮
Collapse an WPF button if and only if this is in the last ListViewItem (row) from the ListView
在 WPF ListView
中,我有 3 列 (GridViewColumn
s)。第一列是自动递增的(1、2、3 等等)。第二个只是一个字符串,最后一列包含 3 个按钮,删除、上移和下移(都在同一列中)。重点说一下我感兴趣的最后一个吧。
我想达到什么目的?
我想折叠 ListView
第一行的向上移动按钮(向上箭头),并折叠 ListView
最后一行的向下移动按钮(向下箭头)。对我来说,第一行是从 1 开始的。见下图。
我做了什么?
我对按钮应用了一种样式以折叠第一行中的上移按钮并且它有效,但现在我不知道如何对最后一行中的下移按钮执行相同的操作(请参阅标有红色圆圈的按钮上图)。
这是我的代码:
<Style x:Key="myButtonStyle" TargetType="Button">
<Style.Triggers>
<!-- Collapse move up button from the first row of the ListView -->
<DataTrigger Binding="{Binding (ItemsControl.AlternationIndex),
RelativeSource={RelativeSource AncestorType=ListViewItem}}" Value="1">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<!-- HOWTO: Collapse move down button from the last row of the ListView here??? -->
</Style.Triggers>
</Style>
正如您在上面看到的,我使用 ItemsControl.AlternationIndex
来为 ListView
的第一列编号。
您需要做的是将当前交替索引与交替计数进行比较。如果 Index == Alternation Count - 1 那么它是最后一行,您可以隐藏该按钮。但是,Value
property of DataTrigger
不是依赖项 属性,因此您不能将交替计数绑定为值。此外,您需要将交替计数减去一个与交替指数进行比较。
您可以做的是使用 MultiBinding
绑定交替索引和交替计数。然后您可以创建一个自定义值转换器来检查上述条件和 returns true
或 false
。作为 DataTrigger
的 Value
,您只需分配 True
.
让我们创建转换器,returns 如果有两个值相差一个。你可以使它不那么抽象,但这样你绑定索引和计数的顺序并不重要。
public class OffByOneToBoolConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values == null || values.Length != 2 || !(values[0] is int value1) || !(values[1] is int value2))
return Binding.DoNothing;
return Math.Abs(value1 - value2) == 1;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new InvalidOperationException();
}
}
对于向下按钮,使用 MultiBinding
创建新样式。
<Style x:Key="myDownButtonStyle" TargetType="Button">
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource OffByOneToBoolConverter}">
<Binding Path="(ItemsControl.AlternationIndex)"
RelativeSource="{RelativeSource AncestorType=ListViewItem}"/>
<Binding Path="(ItemsControl.AlternationCount)" RelativeSource="{RelativeSource AncestorType={x:Type ListView}}"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
不要忘记在范围内的任何资源字典中创建 OffByOneToBoolConverter
的实例。顺便说一下,Up 和 Down 按钮需要单独的按钮样式,因为它们都有排他性条件。对于 Up 按钮,请考虑将 Visibility
设置为 Hidden
,然后即使 Up按钮未显示。
在 WPF ListView
中,我有 3 列 (GridViewColumn
s)。第一列是自动递增的(1、2、3 等等)。第二个只是一个字符串,最后一列包含 3 个按钮,删除、上移和下移(都在同一列中)。重点说一下我感兴趣的最后一个吧。
我想达到什么目的?
我想折叠 ListView
第一行的向上移动按钮(向上箭头),并折叠 ListView
最后一行的向下移动按钮(向下箭头)。对我来说,第一行是从 1 开始的。见下图。
我做了什么? 我对按钮应用了一种样式以折叠第一行中的上移按钮并且它有效,但现在我不知道如何对最后一行中的下移按钮执行相同的操作(请参阅标有红色圆圈的按钮上图)。
这是我的代码:
<Style x:Key="myButtonStyle" TargetType="Button">
<Style.Triggers>
<!-- Collapse move up button from the first row of the ListView -->
<DataTrigger Binding="{Binding (ItemsControl.AlternationIndex),
RelativeSource={RelativeSource AncestorType=ListViewItem}}" Value="1">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<!-- HOWTO: Collapse move down button from the last row of the ListView here??? -->
</Style.Triggers>
</Style>
正如您在上面看到的,我使用 ItemsControl.AlternationIndex
来为 ListView
的第一列编号。
您需要做的是将当前交替索引与交替计数进行比较。如果 Index == Alternation Count - 1 那么它是最后一行,您可以隐藏该按钮。但是,Value
property of DataTrigger
不是依赖项 属性,因此您不能将交替计数绑定为值。此外,您需要将交替计数减去一个与交替指数进行比较。
您可以做的是使用 MultiBinding
绑定交替索引和交替计数。然后您可以创建一个自定义值转换器来检查上述条件和 returns true
或 false
。作为 DataTrigger
的 Value
,您只需分配 True
.
让我们创建转换器,returns 如果有两个值相差一个。你可以使它不那么抽象,但这样你绑定索引和计数的顺序并不重要。
public class OffByOneToBoolConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values == null || values.Length != 2 || !(values[0] is int value1) || !(values[1] is int value2))
return Binding.DoNothing;
return Math.Abs(value1 - value2) == 1;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new InvalidOperationException();
}
}
对于向下按钮,使用 MultiBinding
创建新样式。
<Style x:Key="myDownButtonStyle" TargetType="Button">
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource OffByOneToBoolConverter}">
<Binding Path="(ItemsControl.AlternationIndex)"
RelativeSource="{RelativeSource AncestorType=ListViewItem}"/>
<Binding Path="(ItemsControl.AlternationCount)" RelativeSource="{RelativeSource AncestorType={x:Type ListView}}"/>
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
不要忘记在范围内的任何资源字典中创建 OffByOneToBoolConverter
的实例。顺便说一下,Up 和 Down 按钮需要单独的按钮样式,因为它们都有排他性条件。对于 Up 按钮,请考虑将 Visibility
设置为 Hidden
,然后即使 Up按钮未显示。