两个listview的互斥选择
Mutually exclusive selection of two listviews
我实现了一个类似于 the one made by Diederik Krols. I prefer the approach of using a ListView over using RadioButtons as shown by Jerry Nixon's implementation of the SplitView 的 UWP SplitView。
但是,当我在 SplitView 底部添加辅助命令时遇到问题,而 Diederik 不会这样做。这些辅助命令由绑定到命令集合的另一个 ListView 实现。所以我有两个 ListViews,一次只允许在其中选择一个项目。
我试过两件事:
- 我已将两个 ListView 的 SelectedItem 属性 绑定到同一个对象。这个想法是,如果 SelectedItem 不在绑定到 ItemsSource 的列表中,ListView 可能不会显示选择。可悲的是,它只是继续显示最后选择的项目。
- 我已将每个 ListView 的 SelectedItem 绑定到它自己的 属性。选择 ListView 的一个项目时,ViewModel 将另一个 属性 的 SelectedItem 设置为 'null'。这会产生与 1.
相同的结果
关于如何解决这个问题有什么想法吗?
我遇到了同样的问题。
我有一个修复程序,但我并不为此感到骄傲 ;) 这是一个肮脏的 hack,我希望其他解决方案会出现,这样我也可以更改它。
但是这里是:
首先,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 中,我们将取消选择 'other' 列表视图选择! (此处显示完整代码 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;
}
}
最后要做的是确保我们处理选择并在视图模型中再次清除它以进行下一次迭代(此处显示完整代码 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;
}
}
}
}
我实现了一个类似于 the one made by Diederik Krols. I prefer the approach of using a ListView over using RadioButtons as shown by Jerry Nixon's implementation of the SplitView 的 UWP SplitView。
但是,当我在 SplitView 底部添加辅助命令时遇到问题,而 Diederik 不会这样做。这些辅助命令由绑定到命令集合的另一个 ListView 实现。所以我有两个 ListViews,一次只允许在其中选择一个项目。
我试过两件事:
- 我已将两个 ListView 的 SelectedItem 属性 绑定到同一个对象。这个想法是,如果 SelectedItem 不在绑定到 ItemsSource 的列表中,ListView 可能不会显示选择。可悲的是,它只是继续显示最后选择的项目。
- 我已将每个 ListView 的 SelectedItem 绑定到它自己的 属性。选择 ListView 的一个项目时,ViewModel 将另一个 属性 的 SelectedItem 设置为 'null'。这会产生与 1. 相同的结果
关于如何解决这个问题有什么想法吗?
我遇到了同样的问题。 我有一个修复程序,但我并不为此感到骄傲 ;) 这是一个肮脏的 hack,我希望其他解决方案会出现,这样我也可以更改它。
但是这里是:
首先,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 中,我们将取消选择 'other' 列表视图选择! (此处显示完整代码 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;
}
}
最后要做的是确保我们处理选择并在视图模型中再次清除它以进行下一次迭代(此处显示完整代码 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;
}
}
}
}