当 SelectionMode 设置为 Multiple 时更改 ListViewItems 样式
Change ListViewItems style when SelectionMode is set to Multiple
我有一个 SelectionMode = None
的 ListView。当我将它更改为 Multiple
时,我希望列表中的项目更改它们的样式并在每个项目周围添加边框,以便用户知道他可以 select 它们(参见图像)。我正在使用 MVVMLight,所以如果可以的话,请以 VM 方式提供帮助。无论如何,任何解决方案都将受到赞赏。
好吧,这里的问题与访问我的 ListView 中每个元素的视觉状态有关,更改它以便用户可以看到如何与这些 ListView 项目交互。怎么做:
首先,创建 ListViewItem 模板的副本并添加您的自定义 VisualStates:
<Style TargetType="ListViewItem" x:Key="ListViewItemExpanded">
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="Background" Value="Transparent"/>
<Setter Property="TabNavigation" Value="Local"/>
<Setter Property="IsHoldingEnabled" Value="True"/>
<Setter Property="Margin" Value="0,0,18,2"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border x:Name="OuterContainer">
<VisualStateManager.VisualStateGroups>
<!-- Custom Visual States -->
<VisualStateGroup x:Name="CustomStates">
<VisualState x:Name="Edicion">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="SelectedBorder"
Storyboard.TargetProperty="Opacity" Duration="0" To="1" />
</Storyboard>
</VisualState>
<VisualState x:Name="SoloLectura">
<Storyboard>
<FadeOutThemeAnimation TargetName="SelectedBorder" />
</Storyboard>
</VisualState>
</VisualStateGroup>
...
其次,在你的ListView中为de<DataTemplate>
里面的内容创建一个UserControl:
<UserControl
x:Class="YourNamespace.YourUserControl"
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"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid x:Name="GridUC">
<TextBlock Text="{Binding Path=BindToVMProp}" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Grid>
</UserControl>
第三,在你的 UserControl ("CustomState") 中添加一个自定义 属性,你可以在其中指定你想要设置的 VisualState 的名称,并实现在 UserControl 后面的代码中应用它的逻辑.
public sealed partial class MyUserControl : UserControl
{
public static DependencyProperty CustomStateProperty = DependencyProperty.Register(
"CustomState",
typeof(string),
typeof(MyUserControl),
new PropertyMetadata("SoloLectura", CustomStatePropertyChangedCallback));
public string Estado
{
get
{
return (string)this.GetValue(CustomStateProperty);
}
set
{
this.SetValue(CustomStateProperty, value);
}
}
static void CustomStatePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var item = GetPadre(d as MyUserControl);
VisualStateManager.GoToState(item, e.NewValue.ToString(), true);
}
/// <summary>
/// Gets the listviewitem parent.
/// </summary>
private static ListViewItem GetPadre(FrameworkElement elemento)
{
while (elemento != null)
{
elemento = VisualTreeHelper.GetParent(elemento) as FrameworkElement;
if (elemento is ListViewItem)
break;
}
return elemento as ListViewItem;
}
public FavoritoControl()
{
this.InitializeComponent();
}
}
第四,在您的UserControl所在的视图中,在您的VM中绑定自定义属性,并在需要时将其设置为您的UserControl:
xmlns:local="using:YourNamespace"
<ListView x:Name="MyList" ItemsSource="{Binding CollectionProp}">
<ListView.ItemTemplate>
<DataTemplate>
<local:MyUserControl CustomState="{Binding Path=DataContext.CustomVisualSateProp, ElementName=MyList}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
我在哪里找到我的答案:
listview visual state manager in item template (WinRT, Metro, XAML)
Binding [VisualStateManager] view state to a MVVM viewmodel?
希望这对以后的任何人都有帮助:)
我有一个 SelectionMode = None
的 ListView。当我将它更改为 Multiple
时,我希望列表中的项目更改它们的样式并在每个项目周围添加边框,以便用户知道他可以 select 它们(参见图像)。我正在使用 MVVMLight,所以如果可以的话,请以 VM 方式提供帮助。无论如何,任何解决方案都将受到赞赏。
好吧,这里的问题与访问我的 ListView 中每个元素的视觉状态有关,更改它以便用户可以看到如何与这些 ListView 项目交互。怎么做:
首先,创建 ListViewItem 模板的副本并添加您的自定义 VisualStates:
<Style TargetType="ListViewItem" x:Key="ListViewItemExpanded">
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="Background" Value="Transparent"/>
<Setter Property="TabNavigation" Value="Local"/>
<Setter Property="IsHoldingEnabled" Value="True"/>
<Setter Property="Margin" Value="0,0,18,2"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border x:Name="OuterContainer">
<VisualStateManager.VisualStateGroups>
<!-- Custom Visual States -->
<VisualStateGroup x:Name="CustomStates">
<VisualState x:Name="Edicion">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="SelectedBorder"
Storyboard.TargetProperty="Opacity" Duration="0" To="1" />
</Storyboard>
</VisualState>
<VisualState x:Name="SoloLectura">
<Storyboard>
<FadeOutThemeAnimation TargetName="SelectedBorder" />
</Storyboard>
</VisualState>
</VisualStateGroup>
...
其次,在你的ListView中为de<DataTemplate>
里面的内容创建一个UserControl:
<UserControl
x:Class="YourNamespace.YourUserControl"
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"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid x:Name="GridUC">
<TextBlock Text="{Binding Path=BindToVMProp}" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Grid>
</UserControl>
第三,在你的 UserControl ("CustomState") 中添加一个自定义 属性,你可以在其中指定你想要设置的 VisualState 的名称,并实现在 UserControl 后面的代码中应用它的逻辑.
public sealed partial class MyUserControl : UserControl
{
public static DependencyProperty CustomStateProperty = DependencyProperty.Register(
"CustomState",
typeof(string),
typeof(MyUserControl),
new PropertyMetadata("SoloLectura", CustomStatePropertyChangedCallback));
public string Estado
{
get
{
return (string)this.GetValue(CustomStateProperty);
}
set
{
this.SetValue(CustomStateProperty, value);
}
}
static void CustomStatePropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var item = GetPadre(d as MyUserControl);
VisualStateManager.GoToState(item, e.NewValue.ToString(), true);
}
/// <summary>
/// Gets the listviewitem parent.
/// </summary>
private static ListViewItem GetPadre(FrameworkElement elemento)
{
while (elemento != null)
{
elemento = VisualTreeHelper.GetParent(elemento) as FrameworkElement;
if (elemento is ListViewItem)
break;
}
return elemento as ListViewItem;
}
public FavoritoControl()
{
this.InitializeComponent();
}
}
第四,在您的UserControl所在的视图中,在您的VM中绑定自定义属性,并在需要时将其设置为您的UserControl:
xmlns:local="using:YourNamespace"
<ListView x:Name="MyList" ItemsSource="{Binding CollectionProp}">
<ListView.ItemTemplate>
<DataTemplate>
<local:MyUserControl CustomState="{Binding Path=DataContext.CustomVisualSateProp, ElementName=MyList}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
我在哪里找到我的答案:
listview visual state manager in item template (WinRT, Metro, XAML)
Binding [VisualStateManager] view state to a MVVM viewmodel?
希望这对以后的任何人都有帮助:)