如何知道Windows 10中的通用窗口应用程序中哪个元素是焦点

时间:2016-01-24 16:28:29

标签: c#-4.0 uwp windows-10-universal

我在Windows 10的通用Windows应用程序中有一个xaml页面。此页面包含两个列表框。两个列表框都具有相同的ItemsSource,如

public class CategoryModel
{
 public int CategoryId {get; set;}
 public string CategoryName {get; set;}
 public List<string> ImageURL {get; set;}
}

顶部列表框以水平方式在顶部创建菜单标题,底部列表框以垂直方式在菜单标题的底部创建菜单数据。

问题是如何知道底部的哪个菜单数据元素是焦点,以便我可以在菜单标题中突出显示相同的元素?

                    <ListView x:Name="lvMenuBar" Grid.Column="1" FlowDirection="LeftToRight" ItemsSource="{Binding MenuCategories}" Width="Auto">
                        <ListView.ItemTemplate>
                            <DataTemplate>
                                <Button Click="MenuBarClick" HorizontalAlignment="Center" VerticalAlignment="Top" Tag="{Binding CategoryId}" Content="{Binding CategoryName}" Style="{StaticResource CustomButtonStyle}" FontFamily="Segoe UI" FontWeight="SemiBold" FontSize="18" Margin="0" Padding="20" BorderBrush="Red" BorderThickness="0" Opacity="0.5" Foreground="Black"/>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                        <ListView.ItemsPanel>
                            <ItemsPanelTemplate>
                                <VirtualizingStackPanel Orientation="Horizontal" />
                            </ItemsPanelTemplate>
                        </ListView.ItemsPanel>
                    </ListView>

                    <ListView x:Name="lvMenuBar" Grid.Column="1" FlowDirection="LeftToRight" ItemsSource="{Binding MenuCategories}" Width="Auto">
                        <ListView.ItemTemplate>
                            <DataTemplate>                                    

                                                                                                                                                                                                                                                                                                                                     

以上是我的XAML

2 个答案:

答案 0 :(得分:0)

如果我正确理解了问题,则只要在底部列表中选择该项目,您就可以选择(或以其他方式突出显示)顶部列表中的项目。您可以使用数据绑定来执行此操作,例如:

<ListView
    Grid.Row="0"
    ItemsSource="{Binding MenuCategories}"
    Margin="8"
    SelectedIndex="{Binding SelectedIndex, ElementName=verticalList, Mode=OneWay}"
    >

此处顶部列表的SelectedIndex属性反映了底部列表的属性。

在上下文中,类似这样的事情:

<Page.Resources>
    <Style x:Key="CustomButtonStyle" TargetType="Button" />
</Page.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <ListView
        Grid.Row="0"
        ItemsSource="{Binding MenuCategories}"
        Margin="8"
        SelectedIndex="{Binding SelectedIndex, ElementName=verticalList, Mode=OneWay}"
        >
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="local:CategoryModel">
                <Button
                    HorizontalAlignment="Center"
                    VerticalAlignment="Top"
                    Tag="{Binding CategoryId}"
                    Content="{Binding CategoryName}"
                    Style="{StaticResource CustomButtonStyle}"
                    FontFamily="Segoe UI"
                    FontWeight="SemiBold"
                    FontSize="18"
                    Margin="0"
                    Padding="20"
                    BorderBrush="Red"
                    BorderThickness="0"
                    Opacity="0.5"
                    Foreground="Black"/>
            </DataTemplate>
        </ListView.ItemTemplate>
        <ListView.ItemsPanel>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>
    </ListView>
    <ListView
        x:Name="verticalList"
        Grid.Row="1"
        ItemsSource="{Binding MenuCategories}"
        Margin="8"
        IsItemClickEnabled="True"
        SelectionMode="Single">
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="local:CategoryModel">
                <Button
                    HorizontalAlignment="Center"
                    VerticalAlignment="Top"
                    Tag="{Binding CategoryId}"
                    Content="{Binding CategoryName}"
                    Style="{StaticResource CustomButtonStyle}"
                    FontFamily="Segoe UI"
                    FontWeight="SemiBold"
                    FontSize="18"
                    Margin="0"
                    Padding="20"
                    BorderBrush="Red"
                    BorderThickness="0"
                    Opacity="0.5"
                    Foreground="Black"/>
            </DataTemplate>
        </ListView.ItemTemplate>
        <ListView.ItemsPanel>
            <ItemsPanelTemplate>
                <VirtualizingStackPanel Orientation="Vertical" />
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>
    </ListView>
</Grid>

警告:当您点击其中一个按钮时,ListView没有看到该点击;如果您希望该单击选择项目,请在代码隐藏中执行。

另请注意第二个(垂直)列表中的IsItemClickEnabled属性。

编辑:如果我理解正确,您希望上部水平列表中的选择跟踪下部垂直中的滚动而不是选择。在这种情况下,您需要掌握内置ScrollViewer并执行以下操作:

public MainPage()
{
    InitializeComponent();
    DataContext = this;
    Loaded += (sender, args) =>
        {
            ScrollViewer scrollViewer = FindVisualChild<ScrollViewer>(verticalList);
            if (scrollViewer != null)
            {
                scrollViewer.ViewChanged += (o, eventArgs) =>
                    {
                        int length = MenuCategories.Length;
                        double offset = scrollViewer.VerticalOffset;
                        double height = scrollViewer.ExtentHeight;
                        int index = (int)(length * offset / height);
                        horizontalList.SelectedIndex = index;
                    };
            }
        };
}

private static T FindVisualChild<T>(DependencyObject parent)
    where T : DependencyObject
{
    if (parent != null)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(parent, i);
            T candidate = child as T;
            if (candidate != null)
            {
                return candidate;
            }

            T childOfChild = FindVisualChild<T>(child);
            if (childOfChild != null)
            {
                return childOfChild;
            }
        }
    }

    return default(T);
}

你可能需要在这里试验一下计算;这对我来说有点实验性。

答案 1 :(得分:0)

这段代码解决了我的大部分问题

JOIN