2016-01-24 42 views
0

我在Windows 10中的通用Windows应用程序中有一个xaml页面。此页面包含两个列表框。两个列表框具有像如何知道在Windows 10中的通用Windows应用程序中关注哪个元素10

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

顶部列表框相同的ItemsSource在水平方式上创建菜单标题和底部列表框在垂直方式在菜单头的底部创建菜单数据。

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

    <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

+0

你能分享你的XAML的? – 2016-01-24 22:30:01

+0

我真的不明白,你需要知道,对不起。你想知道,底部列表框中的哪个元素被选中,那么你可以突出显示顶部列表框中的相同元素? –

+0

是@einRobby。我想突出显示顶部,取决于底部的菜单元素 – Vantage

回答

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); 
} 

你可能需要在这里的计算实验;这在我的方面有点实验。

+0

...如果你想让下面的列表也反映上面的列表,只要将绑定模式改为'TwoWay'。:-) –

+0

我想澄清这个答案。这个想法是你的DataContext(你的绑定的来源)和你的XAML中的两个ListView有一个项目和一个整数。您将集合绑定到ListViews,并将两个集合的'Mode = TwoWay'绑定到'SelectedItem'。通过这种方式,当从两个ListView中的任何一个中选择一个项目时,该整数的值会更改,另一个ListView会自动进行通知。 – Corcus

+0

你当然可以将'SelectedIndex'绑定到一个属性,但这对于绑定工作不是必需的。 'SelectedItem'是一个项目引用; 'SelectedIndex'是一个索引。两者都可用于同步列表,并且您只需在其中一个“TwoWay”绑定上实现该功能即可。 –

0

这段代码已经解决了很多我的问题

private double _scrollExtentHeight; 
    private ScrollViewer _scrollViewer; 

_scrollViewer = FindVisualChild<ScrollViewer>(lvMenuItems); 
     if (_scrollViewer != null) 
     { 
      _scrollViewer.ManipulationMode = ManipulationModes.TranslateY; 
      _scrollViewer.DirectManipulationCompleted += scrollViewerDirectManipulationCompleted; 
      _scrollExtentHeight = _scrollViewer.ExtentHeight; 
     } 



    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); 
    } 

    private void scrollViewerDirectManipulationCompleted(object sender, object e) 
    { 
     _menuVM.StartDispatcher(); 
     if (_scrollViewer != null) 
     { 
      int length = _menuVM.Categories.Count; 
      double offset = _scrollViewer.VerticalOffset; 
    //Horizontal scroll viewer 
      List<Button> menuItems = GetAllMenuItemControl(lvMenuBar); 
      int currIndex = 0, index = 0; 
    //Categories height ratio contains the height ratio of each element for total height 
      for (; index < _menuVM.CategoriesHeightRatio.Count; index++) 
      { 
       if ((_menuVM.CategoriesHeightRatio[index - 1 > 0 ? index - 1 : 0] * _scrollExtentHeight) < offset && (_menuVM.CategoriesHeightRatio[index] * _scrollExtentHeight) >= offset) 
       { 
        currIndex = index; 
       } 
       else 
       { 
        menuItems[index].BorderThickness = new Thickness(0, 0, 0, 0); 
        menuItems[index].Opacity = 0.5; 
       } 
      } 
      menuItems[currIndex].BorderThickness = new Thickness(0, 0, 0, 2); 
      menuItems[currIndex].Opacity = 1; 
      var transform = lvMenuBar.TransformToVisual(menuItems[currIndex]); 
      Point absolutePoint = transform.TransformPoint(new Point(0, 0)); 
      svMenuBar.ChangeView(Math.Abs(absolutePoint.X), null, null, false); 
     } 
    } 

    private List<Button> GetAllMenuItemControl(DependencyObject parent) 
    { 
     var _List = new List<Button>(); 
     for (int index = 0; index < VisualTreeHelper.GetChildrenCount(parent); index++) 
     { 
      var _Child = VisualTreeHelper.GetChild(parent, index); 
      if (_Child is Button) 
       _List.Add(_Child as Button); 
      _List.AddRange(GetAllMenuItemControl(_Child)); 
     } 
     return _List; 
    } 
相关问题