我如何更改被单击的ListView项(UWP)的内容?就像Mail App一样

问题描述 投票:-6回答:2

这是我想要做的。我有一个非常简单的ListView,它具有一个dataTemplate,该模板绑定到页面代码中的ObservableCollection。很简单吧?现在,我想在单击列表时立即更改列表视图中单个项目的高度。

Windows的Mail和Wifi-Ui使用这种操纵。检查图像以更好地理解。

可能的解决方案:-我已经在Xaml中定义了两个数据模板作为资源,并且在单击事件中,我正在更改listview的ItemTemplateSelector属性。但是问题在于,列表视图中的每个项目都会将自身更改为该数据模板,这很有意义。但这不是我想要实现的。我只想更改单击列表视图中单个项目的高度,甚至在单击某些动画时也是如此。

可能的第二种解决方案:我在Xaml中仅定义一个包含网格的数据模板。现在我正在做的是将网格高度绑定到c#代码中的公共属性。在Itemclick事件中,我得到e.ClickedItem,然后将属性的高度更改为其他值。这应该可以工作,但是绑定到“网格高度”的值会更改,但不会反映在UI中。它与{Bind statement}有关系吗,我需要使用{x:Bind}吗?

enter image description here这是折叠后的版本的样子……

enter image description here这是扩展版本的外观,整个扩展过程都是通过动画进行的。

c# xaml uwp
2个回答
3
投票

可能的解决方案1

您可以有两个共享某些UI的数据模板,一个模板比另一个模板具有更多的元素。您将遇到的问题是如何快速单击以更新到其他模板。

我最近回答了一个问题here,该问题通过订阅IsSelected属性来解决此问题,并手动重置ContentTemplateSelector以强制更新模板。

但是将完整模板交换给我是一个过大的决定,我也倾向于您的第二个解决方案。

可能的解决方案2

好像您正在尝试通过ViewModel中的属性更新Height,这可能有效。但是对我来说,这种UI逻辑最好放在后面的代码中,您可以在Grid回调中轻松获取ItemClick并为其分配一个不同的Height

但是如果您在其他地方有类似要求的类似ListView,该怎么办?您最终会得到很多重复的代码隐藏代码。这就是为什么我实际上要扩展ListViewItem功能以适应在ItemTemplate中扩展UI的某些部分的原因。所以这是-

首先,我们创建一个从ExtendedListViewItem继承的ListViewItem。此扩展控件有两件事-

  1. 创建一个名为IsExpandable附加属性,稍后会附加到ListView数据内的某些UI元素模板。
  2. 由于每次单击ListViewItem时,IsSelected属性都会更新,因此我们可以对其进行监视以相应地显示和隐藏IsExpandable元素。

public class ExtendedListViewItem : ListViewItem
{
    public ExtendedListViewItem()
    {
        // This could be set in its default style in Generic.xaml instead.
        HorizontalContentAlignment = HorizontalAlignment.Stretch;

        RegisterPropertyChangedCallback(IsSelectedProperty, (s, e) =>
        {
            // Children() is available at
            // https://github.com/JustinXinLiu/Continuity/blob/0cc3d7556c747a060d40bae089b80eb845da84fa/Continuity/Extensions/UtilExtensions.cs#L25
            foreach (var child in this.Children())
            {
                if (GetIsExpandable(child))
                {
                    child.Visibility = IsSelected ? Visibility.Visible : Visibility.Collapsed;
                }
            }
        });
    }

    public static void SetIsExpandable(DependencyObject element, bool value) =>
        element.SetValue(IsExpandableProperty, value);
    public static bool GetIsExpandable(DependencyObject element) =>
        (bool)element.GetValue(IsExpandableProperty);
    public static readonly DependencyProperty IsExpandableProperty = DependencyProperty.RegisterAttached(
        "IsExpandable",
        typeof(bool),
        typeof(ExtendedListViewItem),
        new PropertyMetadata(default(bool), (s, e) =>
            {
                var element = (UIElement)s;
                element.Visibility = (bool)e.NewValue ? Visibility.Collapsed : Visibility.Visible;
            }));
}

接下来,我们还需要扩展ListView控件以将我们的ExtendedListViewItem控件作为其子级,而不是默认的ListViewItem


public class ExtendedListView : ListView
{
    protected override DependencyObject GetContainerForItemOverride()
    {
        return new ExtendedListViewItem();
    }
}

最后,是时候将IsExpandable标志附加到右侧元素了。例如,我只希望单击该项目时显示文本-


<DataTemplate x:Key="MyItemTemplate">
    <StackPanel Margin="24">
        <Image HorizontalAlignment="Left" Source="{Binding Property3}" Width="48" Height="48" />

        <StackPanel Margin="12" local:ExtendedListViewItem.IsExpandable="True">
            <TextBlock Text="{Binding Property1}" Style="{StaticResource TitleTextBlockStyle}" />
            <TextBlock Text="{Binding Property2}" Style="{StaticResource CaptionTextBlockStyle}" />
        </StackPanel>
    </StackPanel>
</DataTemplate>

<local:ExtendedListView ContainerContentChanging="OnMyListViewContainerContentChanging" 
                        ItemTemplate="{StaticResource MyItemTemplate}" 
                        ItemsSource="{Binding Groups}" />

奖励

忽略ExtendedListView控件正在订阅名为ContainerContentChanging的事件吗?在这里可以为项目创建隐式偏移动画,以使布局更改更有趣。


    private void OnMyListViewContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
    {
        var containerVisual = ElementCompositionPreview.GetElementVisual(args.ItemContainer);

        if (args.InRecycleQueue)
        {
            containerVisual.ImplicitAnimations = null;
        }
        else
        {
            // EnableImplicitAnimation() is available at
            // https://github.com/JustinXinLiu/Continuity/blob/0015a96897c138e09d8604267df46da936b66838/Continuity/Extensions/CompositionExtensions.Implicit.cs#L144
            containerVisual.EnableImplicitAnimation(VisualPropertyType.Offset, 400.0f);
        }
    }

结果enter image description here

希望这会有所帮助!


-1
投票

[好,抱歉,我现在明白了。首先,您需要在xaml中设置列表视图的名称和原始高度。

<ListView x:Name="GenericName" height="x"></ListView>

[下一步,您想要在代码后面添加有关单击按钮的代码。在这个范围内。您需要输入一条声明,将高度设置为其他值。实际上很简单。

    private void Button_Click (object sender, RoutedEventArgs e)
{
        GenericName.Height = NewValue;
}

这应该起作用。

© www.soinside.com 2019 - 2024. All rights reserved.