【问题标题】:MasterDetailView UWP - Access the ListView (or make it scroll)MasterDetailView UWP - 访问 ListView(或使其滚动)
【发布时间】:2017-07-10 10:19:28
【问题描述】:

我最近发现了 UWP 社区工具包,我很喜欢它。我现在正在使用MasterDetailView,它几乎可以满足我的需要:但它缺少一件重要的事情:我无法访问内部的“ListView”。

在我的应用程序中,我有两个按钮:前进和后退,当按下它们时,我只需在列表中前进和后退。我发现了一个像这样访问 prev/next 元素的技巧:

public void GoForward()
    {
        if (MasterDetailView.Items.Count > 0)
        {
            bool isNextGood = false;
            MyItem selectedItem = MasterDetailView.Items[MasterDetailView.Items.Count - 1] as MyItem;

            foreach (var v in MasterDetailView.Items)
            {
                if (isNextGood)
                {
                    selectedItem = v as MyItem;
                    break;
                }

                if (v == MasterDetailView.SelectedItem)
                    isNextGood = true;
            }

            MasterDetailView.SelectedItem = selectedItem;
        }
    }

这只是因为我无法访问“SelectedIndex”并且我只有 SelectedItem 可用。现在,显然不是所有的项目都可以同时可见,所以 MasterDetailView 提供了一个带有滚动条的横向 ListView。当按下我的下一个/上一个按钮时,SelectedItem 会发生变化,但不会在所选元素处滚动:选择前进/后退,但列表被锁定。这会产生非常负面的反馈,因为我在列表中的某处丢失了我的选择,我必须搜索它。

我该如何解决呢?我尝试这种方法:


1) 找到 MasterDetailView 的样式。在里面我找到了一个 ListViewStyle,所以我尝试在 App.xaml.cs 中放入一个简单的“SelectionChanged”事件并处理它。

<ListView x:Name="MasterList"
                                      Grid.Row="1"
                                      IsTabStop="False"
                                      ItemContainerStyle="{TemplateBinding ItemContainerStyle}"
                                      ItemTemplate="{TemplateBinding ItemTemplate}"
                                      ItemTemplateSelector="{TemplateBinding ItemTemplateSelector}"
                                      ItemsSource="{TemplateBinding ItemsSource}"
                                      SelectedItem="{Binding SelectedItem, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
                                      SelectionChanged="MasterList_SelectionChanged"/>

CS:

private void MasterList_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        ListView list = sender as ListView;
        list.ScrollIntoView(list.SelectedItem);
    }

但是,如前所述,“无法在应用程序类 XAML 文件中设置事件”


2) 考虑采用 SelectedItem 的父项:我尝试在 ListViewItem 中转换 SelectedItem,然后访问父项,但在第一次转换时失败,因为 SelectedItem 似乎不是 ListViewItem,但它属于“MyItem “ 类型。像这样,我无法访问父级。

private void MasterDetailView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var item = MasterDetailView.SelectedItem as ListViewItem;
        var parent = item.Parent;
        var list = parent as ListView;
    }

所以我在这里......我不想丢掉我在 MasterDetailView 上的所有工作以传递给另一个控件。是否有任何简单的方法可以访问列表,或者只是在我更改选择时滚动列表?只想做一件事,像这样:

private void List_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ListView list = sender as ListView;
            list.ScrollIntoView(list.SelectedItem);
        }

只需在发生选择时滚动到选择,但我没有简单的ListView但是MasterDetailView控件。即使它完全在 XAML 中完成:对我来说最重要的是滚动这个列表!

谢谢。


解决方案

这个方法太棒了。只需复制粘贴即可。

public static T FindChildOfType<T>(DependencyObject root) where T : class
    {
        var queue = new Queue<DependencyObject>();
        queue.Enqueue(root);
        while (queue.Count > 0)
        {
            DependencyObject current = queue.Dequeue();
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(current); i++)
            {
                var child = VisualTreeHelper.GetChild(current, i);
                var typedChild = child as T;
                if (typedChild != null)
                {
                    return typedChild;
                }
                queue.Enqueue(child);
            }
        }
        return null;
    }

然后只需使用它来检索列表并使其滚动。是的宝贝!

private void MasterDetailView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var v = FindChildOfType<ListView>(MasterDetailView);
        v.ScrollIntoView(MasterDetailView.SelectedItem);
    }

请注意,“MasterDerailView”是我的元素的 x:Name,而不是类。

【问题讨论】:

  • MasterDetailsView 默认有 SelectionChanged 事件。 &lt;controls:MasterDetailsView SelectionChanged="MasterDetailPanel_SelectionChanged"/&gt;
  • Viajy Nirmal:是的,确实如此。但它没有什么特别的用途。您可以像往常一样检索 SelectedItem(即 MyItem 对象)和我的对象列表,但不能检索 ListView 或 ScrollingEvents。所以没用。我无法使用此事件来检索列表。我知道存在,但我无法访问列表本身来控制滚动

标签: xaml uwp c#-3.0 master-detail windows-community-toolkit


【解决方案1】:

您可以使用 FindChildOfType 实现通过 VisualTreeHelper 获取 ListView ,如本答案所示: Windows UWP - How to programmatically scroll ListView in ContentTemplate

【讨论】:

  • 天哪,就是这样!我会立即更新答案!
猜你喜欢
  • 2018-05-23
  • 2020-09-22
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 2019-03-15
  • 1970-01-01
  • 2017-08-10
  • 2017-02-20
相关资源
最近更新 更多