使用VisualStateManager隐藏或显示ListViewItem的堆栈面板 [英] Hide or Show stackpanel of ListViewItem with VisualStateManager

查看:87
本文介绍了使用VisualStateManager隐藏或显示ListViewItem的堆栈面板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对C#UWP中的VisualStateManager不太熟悉,我需要您的帮助来隐藏或显示ListViewItem中的堆栈面板.

<ListView.ItemTemplate>
<DataTemplate>
    <Grid Width="500">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>

        <StackPanel Orientation="Horizontal">
            <Image Height="45" Width="45" Margin="0,8,0,8" Source="../../Assets/ViewBox.png" Stretch="UniformToFill"/>
            <StackPanel Orientation="Vertical" VerticalAlignment="Top" Margin="8,8,0,0">
                <TextBlock Text="Test" Style="{StaticResource BaseTextBlockStyle}" />
                <TextBlock Text="test1" Margin="0,4,8,0" Style="{StaticResource BodyTextBlockStyle}" />
            </StackPanel>
        </StackPanel>

        <StackPanel x:Name="EDITOR_PANEL" Grid.Row="1" Orientation="Horizontal" Visibility="Collapsed">
            <Button Content="Edit" />
            <Button Content="Delete" />
        </StackPanel>

        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
                <VisualState x:Name="Normal">
                    <Storyboard>
                        <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" />
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Selected">
                    <VisualState.Setters>
                        <Setter Target="EDITOR_PANEL.Visibility" Value="Visible"></Setter>
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Grid>
</DataTemplate>
</ListView.ItemTemplate>

我想做的是这样的:

当我选择列表视图中的一个项目时,它用两个按钮显示EDITOR_PANEL;如果我选择另一个,则上一个选定的项目将折叠,而当前的项目将显示EDITOR_PANEL,依此类推. /p>

你有什么主意吗?

解决方案

一种解决方案是创建一个 UserControl ,其中包含要在ListViewItem中公开的所有控件.

然后,从后面的代码中,您可以在ListView事件SelectionChanged上更新VisualState.

这是一个有效的示例:

UserControl视图:

<UserControl
    x:Class="App4.EditablePanel"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App4"
    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 Width="500">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>

        <StackPanel Orientation="Horizontal">
            <Image Height="45" Width="45" Margin="0,8,0,8" Source="../../Assets/ViewBox.png" Stretch="UniformToFill"/>
            <StackPanel Orientation="Vertical" VerticalAlignment="Top" Margin="8,8,0,0">
                <TextBlock Text="{Binding Title}" Style="{StaticResource BaseTextBlockStyle}" />
                <TextBlock Text="{Binding Headline}" Margin="0,4,8,0" Style="{StaticResource BodyTextBlockStyle}" />
            </StackPanel>
        </StackPanel>

        <StackPanel x:Name="EDITOR_PANEL" Grid.Row="1" Orientation="Horizontal" Visibility="Collapsed">
            <Button Content="Edit" />
            <Button Content="Delete" />
        </StackPanel>

        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
                <VisualState x:Name="Normal">
                </VisualState>
                <VisualState x:Name="Selected">
                    <VisualState.Setters>
                        <Setter Target="EDITOR_PANEL.Visibility" Value="Visible"></Setter>
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Grid>
</UserControl>

UserControl背后的代码:

public sealed partial class EditablePanel : UserControl
{
    public EditablePanel()
    {
        this.InitializeComponent();
    }

    public void SetInEditMode()
    {
        VisualStateManager.GoToState(this, "Selected", true);
    }

    public void SetInViewMode()
    {
        VisualStateManager.GoToState(this, "Normal", true);
    }
}

MainPage视图:

<Page
    x:Class="App4.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App4"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    DataContext="{Binding RelativeSource={RelativeSource Self}}">

    <ListView ItemsSource="{Binding Items}" SelectionChanged="ListView_SelectionChanged">
        <ListView.ItemTemplate>
            <DataTemplate>
                <local:EditablePanel></local:EditablePanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Page>

MainPage背后的代码:

public sealed partial class MainPage : Page
{
    private List<Item> items;

    public MainPage()
    {
        items = new List<Item>()
        {
            new Item() { Title = "3D Build", Headline="MS Corp" },
            new Item() { Title = "7Zip", Headline="Igor Pavlov" },
            new Item() { Title = "Photoshop", Headline = "Adobe"}
        };


        this.InitializeComponent();
    }

    public List<Item> Items { get { return items; } }

    private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var lv = sender as ListView;
        if (e.RemovedItems.Count > 0)
        {
            foreach (var item in e.RemovedItems)
            {
                var container = lv.ContainerFromItem(item) as ListViewItem;
                var panel = container.ContentTemplateRoot as EditablePanel;
                panel.SetInViewMode();
            }
        }
        if (e.AddedItems.Count > 0)
        {
            foreach (var item in e.AddedItems)
            {
                var container = lv.ContainerFromItem(item) as ListViewItem;
                var panel = container.ContentTemplateRoot as EditablePanel;
                panel.SetInEditMode();
            }
        }
    }
}

public class Item
{
    public string Title { get; set; }
    public string Headline { get; set; }
}

I'm not really familiar with the VisualStateManager in C# UWP, and I need your help to hide or show a stack panel in my ListViewItem.

<ListView.ItemTemplate>
<DataTemplate>
    <Grid Width="500">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>

        <StackPanel Orientation="Horizontal">
            <Image Height="45" Width="45" Margin="0,8,0,8" Source="../../Assets/ViewBox.png" Stretch="UniformToFill"/>
            <StackPanel Orientation="Vertical" VerticalAlignment="Top" Margin="8,8,0,0">
                <TextBlock Text="Test" Style="{StaticResource BaseTextBlockStyle}" />
                <TextBlock Text="test1" Margin="0,4,8,0" Style="{StaticResource BodyTextBlockStyle}" />
            </StackPanel>
        </StackPanel>

        <StackPanel x:Name="EDITOR_PANEL" Grid.Row="1" Orientation="Horizontal" Visibility="Collapsed">
            <Button Content="Edit" />
            <Button Content="Delete" />
        </StackPanel>

        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
                <VisualState x:Name="Normal">
                    <Storyboard>
                        <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" />
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="Selected">
                    <VisualState.Setters>
                        <Setter Target="EDITOR_PANEL.Visibility" Value="Visible"></Setter>
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Grid>
</DataTemplate>
</ListView.ItemTemplate>

What I want to do is something like this:

When I select an item of my listview, it show the EDITOR_PANEL with the two buttons, and if I select another one, it the previous selected item collapses and the current one shows the EDITOR_PANEL and so on.

Do you have any ideas?

解决方案

One solution is to create a UserControl which contains all the controls you want to expose in your ListViewItem.

Then, from code behind, you can update the VisualState on the ListView event SelectionChanged.

Here is a working sample:

The UserControl view:

<UserControl
    x:Class="App4.EditablePanel"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App4"
    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 Width="500">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>

        <StackPanel Orientation="Horizontal">
            <Image Height="45" Width="45" Margin="0,8,0,8" Source="../../Assets/ViewBox.png" Stretch="UniformToFill"/>
            <StackPanel Orientation="Vertical" VerticalAlignment="Top" Margin="8,8,0,0">
                <TextBlock Text="{Binding Title}" Style="{StaticResource BaseTextBlockStyle}" />
                <TextBlock Text="{Binding Headline}" Margin="0,4,8,0" Style="{StaticResource BodyTextBlockStyle}" />
            </StackPanel>
        </StackPanel>

        <StackPanel x:Name="EDITOR_PANEL" Grid.Row="1" Orientation="Horizontal" Visibility="Collapsed">
            <Button Content="Edit" />
            <Button Content="Delete" />
        </StackPanel>

        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
                <VisualState x:Name="Normal">
                </VisualState>
                <VisualState x:Name="Selected">
                    <VisualState.Setters>
                        <Setter Target="EDITOR_PANEL.Visibility" Value="Visible"></Setter>
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Grid>
</UserControl>

The UserControl codebehind:

public sealed partial class EditablePanel : UserControl
{
    public EditablePanel()
    {
        this.InitializeComponent();
    }

    public void SetInEditMode()
    {
        VisualStateManager.GoToState(this, "Selected", true);
    }

    public void SetInViewMode()
    {
        VisualStateManager.GoToState(this, "Normal", true);
    }
}

The MainPage view:

<Page
    x:Class="App4.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App4"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    DataContext="{Binding RelativeSource={RelativeSource Self}}">

    <ListView ItemsSource="{Binding Items}" SelectionChanged="ListView_SelectionChanged">
        <ListView.ItemTemplate>
            <DataTemplate>
                <local:EditablePanel></local:EditablePanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Page>

The MainPage code behind:

public sealed partial class MainPage : Page
{
    private List<Item> items;

    public MainPage()
    {
        items = new List<Item>()
        {
            new Item() { Title = "3D Build", Headline="MS Corp" },
            new Item() { Title = "7Zip", Headline="Igor Pavlov" },
            new Item() { Title = "Photoshop", Headline = "Adobe"}
        };


        this.InitializeComponent();
    }

    public List<Item> Items { get { return items; } }

    private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var lv = sender as ListView;
        if (e.RemovedItems.Count > 0)
        {
            foreach (var item in e.RemovedItems)
            {
                var container = lv.ContainerFromItem(item) as ListViewItem;
                var panel = container.ContentTemplateRoot as EditablePanel;
                panel.SetInViewMode();
            }
        }
        if (e.AddedItems.Count > 0)
        {
            foreach (var item in e.AddedItems)
            {
                var container = lv.ContainerFromItem(item) as ListViewItem;
                var panel = container.ContentTemplateRoot as EditablePanel;
                panel.SetInEditMode();
            }
        }
    }
}

public class Item
{
    public string Title { get; set; }
    public string Headline { get; set; }
}

这篇关于使用VisualStateManager隐藏或显示ListViewItem的堆栈面板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆