是否可以对 ListView 的每个项目应用不同的透明度?
Can transparency be applied differently for each item of ListView?
我正在尝试创建一个显示简单聊天消息的控件。
最多显示 10 条消息。
最新消息始终添加到 ListView
的末尾
最早的消息位于 ListView
.
的顶部
我想让旧消息越来越模糊(Opacity
)。
你对如何做到这一点有什么想法吗?
不支持 out-of-the-box,但您可以使用技巧轻松实现此行为 固定数量的项目。每个 ItemsControl
都有一个 built-in 交替机制,通常用于根据交替索引更改行的样式或外观。
在这种情况下,我们利用此功能获取 ListViewItem
的索引并设置 Opacity
.
- 将
AlternationCount
属性 设置为 collection. 的 固定大小
- 添加项目容器样式以设置
ListViewItem
的 Opacity
。
- 为每个项目添加一个
AlternationConverter
和不透明度。
- 使用转换器绑定附件 属性
AlternationIndex
。
这样,AlternationIndex
用于应用相应的不透明度值。
<ListView ItemsSource="{Binding YourItemsSource}"
AlternationCount="10">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Style.Resources>
<AlternationConverter x:Key="AlternationIndexToOpacityConverter">
<system:Double>0.1</system:Double>
<system:Double>0.2</system:Double>
<system:Double>0.3</system:Double>
<system:Double>0.4</system:Double>
<system:Double>0.5</system:Double>
<system:Double>0.6</system:Double>
<system:Double>0.7</system:Double>
<system:Double>0.8</system:Double>
<system:Double>0.9</system:Double>
<system:Double>1.0</system:Double>
</AlternationConverter>
</Style.Resources>
<Setter Property="Opacity" Value="{Binding (ItemsControl.AlternationIndex), RelativeSource={RelativeSource Self}, Converter={StaticResource AlternationIndexToOpacityConverter}}"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
string
的任意 collection 的结果如下所示。
如果您想对不透明度应用更复杂的算法,请创建一个自定义值转换器。
public class AlternationIndexToOpacityConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values == null || values.Length != 2)
return DependencyProperty.UnsetValue;
if (!(values[0] is int alternationCount) || !(values[1] is int alternationIndex))
return DependencyProperty.UnsetValue;
var proportion = (double) alternationIndex / (alternationCount - 1);
return 0.3 + proportion * 0.7;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new InvalidOperationException();
}
}
在这种情况下,您还需要绑定 AlternationCount
属性,以获得 collection 大小。
<ListView ItemsSource="{Binding YourItemsSource}"
AlternationCount="10">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Style.Resources>
<local:AlternationIndexToOpacityConverter x:Key="AlternationIndexToOpacityConverter"/>
</Style.Resources>
<Setter Property="Opacity">
<Setter.Value>
<MultiBinding Converter="{StaticResource AlternationIndexToOpacityConverter}">
<Binding Path="AlternationCount" RelativeSource="{RelativeSource AncestorType={x:Type ListView}}"/>
<Binding Path="(ItemsControl.AlternationIndex)" RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
结果看起来相似,但在本例中,最小不透明度为 0.3
。
已经回答了,但我会给出另一个想法来实现这个没有背后的代码。
这个想法只是在 ListView
上放置一个不透明度渐变网格。从上到下,从Listview
的顶部模糊,然后在ListView
的底部清晰。确保设置 IsHitTestVisible
为 false,并将画笔颜色更改为 ListView
的背景。以及 ScrollBar
区域的保证金。
我测试了它,它有效。但质量马马虎虎。因为 Select 项目高亮颜色也变得不透明,并且网格覆盖可以覆盖滚动条区域。
但对于谁想要简单的方法,我会留下这个评论。如果您的应用程序不需要 ScrollBar
.
,这将是简单的方法
<Grid IsHitTestVisible="False" Margin="0 0 18 0">
<Grid.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#bbffffff" Offset="0.1"/>
<GradientStop Color="#77ffffff" Offset="0.3"/>
<GradientStop Color="#00ffffff" Offset="1.0"/>
</LinearGradientBrush>
</Grid.Background>
</Grid>
我正在尝试创建一个显示简单聊天消息的控件。
最多显示 10 条消息。
最新消息始终添加到 ListView
的末尾
最早的消息位于 ListView
.
我想让旧消息越来越模糊(Opacity
)。
你对如何做到这一点有什么想法吗?
不支持 out-of-the-box,但您可以使用技巧轻松实现此行为 固定数量的项目。每个 ItemsControl
都有一个 built-in 交替机制,通常用于根据交替索引更改行的样式或外观。
在这种情况下,我们利用此功能获取 ListViewItem
的索引并设置 Opacity
.
- 将
AlternationCount
属性 设置为 collection. 的 固定大小
- 添加项目容器样式以设置
ListViewItem
的Opacity
。 - 为每个项目添加一个
AlternationConverter
和不透明度。 - 使用转换器绑定附件 属性
AlternationIndex
。
这样,AlternationIndex
用于应用相应的不透明度值。
<ListView ItemsSource="{Binding YourItemsSource}"
AlternationCount="10">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Style.Resources>
<AlternationConverter x:Key="AlternationIndexToOpacityConverter">
<system:Double>0.1</system:Double>
<system:Double>0.2</system:Double>
<system:Double>0.3</system:Double>
<system:Double>0.4</system:Double>
<system:Double>0.5</system:Double>
<system:Double>0.6</system:Double>
<system:Double>0.7</system:Double>
<system:Double>0.8</system:Double>
<system:Double>0.9</system:Double>
<system:Double>1.0</system:Double>
</AlternationConverter>
</Style.Resources>
<Setter Property="Opacity" Value="{Binding (ItemsControl.AlternationIndex), RelativeSource={RelativeSource Self}, Converter={StaticResource AlternationIndexToOpacityConverter}}"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
string
的任意 collection 的结果如下所示。
如果您想对不透明度应用更复杂的算法,请创建一个自定义值转换器。
public class AlternationIndexToOpacityConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values == null || values.Length != 2)
return DependencyProperty.UnsetValue;
if (!(values[0] is int alternationCount) || !(values[1] is int alternationIndex))
return DependencyProperty.UnsetValue;
var proportion = (double) alternationIndex / (alternationCount - 1);
return 0.3 + proportion * 0.7;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new InvalidOperationException();
}
}
在这种情况下,您还需要绑定 AlternationCount
属性,以获得 collection 大小。
<ListView ItemsSource="{Binding YourItemsSource}"
AlternationCount="10">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Style.Resources>
<local:AlternationIndexToOpacityConverter x:Key="AlternationIndexToOpacityConverter"/>
</Style.Resources>
<Setter Property="Opacity">
<Setter.Value>
<MultiBinding Converter="{StaticResource AlternationIndexToOpacityConverter}">
<Binding Path="AlternationCount" RelativeSource="{RelativeSource AncestorType={x:Type ListView}}"/>
<Binding Path="(ItemsControl.AlternationIndex)" RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
结果看起来相似,但在本例中,最小不透明度为 0.3
。
已经回答了,但我会给出另一个想法来实现这个没有背后的代码。
这个想法只是在 ListView
上放置一个不透明度渐变网格。从上到下,从Listview
的顶部模糊,然后在ListView
的底部清晰。确保设置 IsHitTestVisible
为 false,并将画笔颜色更改为 ListView
的背景。以及 ScrollBar
区域的保证金。
我测试了它,它有效。但质量马马虎虎。因为 Select 项目高亮颜色也变得不透明,并且网格覆盖可以覆盖滚动条区域。
但对于谁想要简单的方法,我会留下这个评论。如果您的应用程序不需要 ScrollBar
.
<Grid IsHitTestVisible="False" Margin="0 0 18 0">
<Grid.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#bbffffff" Offset="0.1"/>
<GradientStop Color="#77ffffff" Offset="0.3"/>
<GradientStop Color="#00ffffff" Offset="1.0"/>
</LinearGradientBrush>
</Grid.Background>
</Grid>