两个列表视图的互斥选择

时间:2016-02-12 09:51:22

标签: xaml windows-store-apps win-universal-app

我实现了类似于the one made by Diederik Krols的UWP SplitView。我更喜欢使用ListView而不是Jerry Nixon's implementation of the SplitView所示的使用RadioButtons的方法。

但是,当我在SplitView底部添加辅助命令时遇到问题,而Diederik却没有这样做。这些辅助命令由绑定到命令集合的另一个ListView实现。所以我有两个ListViews,一次只允许在它们中选择一个项目。

我尝试了两件事:

  1. 我将两个ListView的SelectedItem属性绑定到同一个对象。我的想法是,如果SelectedItem不在绑定到ItemsSource的列表中,ListView可能不显示选择。可悲的是,它只是显示最后选择的项目。
  2. 我将每个ListView的SelectedItem绑定到它自己的属性。当选择其中一个ListViews项时,ViewModel将另一个属性的SelectedItem设置为“null”。这产生与1中相同的结果。
  3. 关于如何解决这个问题的任何想法?

1 个答案:

答案 0 :(得分:1)

我遇到了同样的问题。 我有一个解决办法,但我并不为此感到骄傲;)它是一个肮脏的黑客,我希望其他解决方案能够呈现,所以我也可以改变它。

但这是:

首先,listviews连接到SelectionChanged事件,即使我们还将所选项目绑定到viewmodel(此处显示完整代码https://github.com/AppCreativity/Kliva/blob/master/src/Kliva/Controls/SidePaneControl.xaml

<ListView x:Name="TopMenu"
          SelectionChanged="OnTopMenuSelectionChanged"
          Background="Transparent"
          ItemsSource="{x:Bind ViewModel.TopMenuItems}"
          ItemTemplateSelector="{StaticResource MenuItemTemplateSelector}"                 
          ItemContainerStyle="{StaticResource MenuItemContainerStyle}"
          SelectedItem="{x:Bind ViewModel.SelectedTopMenuItem, Mode=TwoWay, Converter={StaticResource XBindItemCastingConverter}}"
          Grid.Row="0" />

在SelectionChanged中,我们将取消选择其他&#39;其他&#39;列表视图选择! (此处显示完整代码https://github.com/AppCreativity/Kliva/blob/master/src/Kliva/Controls/SidePaneControl.xaml.cs) 请注意,我们需要跟踪我们已经在取消选择过程中,否则我们将以无限循环结束。这是通过_listViewChanging字段完成的。

private void OnBottomMenuSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (!_listViewChanging)
    {
        _listViewChanging = true;
        TopMenu.SelectedIndex = -1;
        _listViewChanging = false;
    }
}

最后要做的是确保我们处理选择并在viewmodel中再次清除它以进行下一次尝试(此处显示完整代码https://github.com/AppCreativity/Kliva/blob/master/src/Kliva/ViewModels/SidePaneViewModel.cs

public MenuItem SelectedBottomMenuItem
{
    get { return _selectedBottomMenuItem; }
    set
    {
        if (Set(() => SelectedBottomMenuItem, ref _selectedBottomMenuItem, value))
        {
            if (value != null)
            {
                if (string.IsNullOrEmpty(SelectedBottomMenuItem.Title))
                    HamburgerCommand.Execute(null);

                if (SelectedBottomMenuItem.Title.Equals("settings", StringComparison.OrdinalIgnoreCase))
                    SettingsCommand.Execute(null);

                SelectedBottomMenuItem = null;
            }
        }                
    }
}