【问题标题】:Issue with multiple ListBoxes and their SelectedItem多个 ListBox 及其 SelectedItem 的问题
【发布时间】:2018-03-22 22:11:35
【问题描述】:

我正在使用 WPF(C#、Visual Studio 2010、MVVM Light)并且遇到三个列表框控件的问题。

所以情况如下:我有三个列表框。第一个是作为“示例”的 ID 列表。第二个也是“相关项目”的 ID 列表。它们是我的程序中代表动词的类(如语言类型)的示例和相关项目。

如果您单击这两个 ListBox 中的任何一个,它将填充第三个 ListBox。两者互不影响,只有第三种。第三个不影响其他两个。第三个一次只能容纳一件物品。

它运作良好,除了一种情况。假设“示例”ListBox 包含 ID 100002 和 100003。假设“相关项”ListBox 包含 ID 100004 和 100005。我单击 100002,因此第一个 ListBox 的选定项变为该项。第三个列表框显示 100002 的详细信息(应该如此)。然后我在第二个 Listbox 中单击 100004。这成为第二个 Listbox 的选定项,第三个 Listbox 显示 100004。到目前为止很好。但是现在让我们说无论出于何种原因我想再次回到 100002。由于它仍然是第一个 Listbox 中的选定项,因此再次单击它没有任何效果。视图模型中的设置器甚至没有被触发,所以我不能在那里做任何事情。事实上,我不确定在这种情况下我的选择是什么。我确实考虑过使用“示例”的设置器将“相关项目”的选定项目设置为空,反之亦然,但我意识到这会导致无限循环。

我还尝试使用一个变量来链接到前两个 ListBox 的选定项目,但这并没有解决问题。

我还尝试了以下方法:

private LanguageItemViewModel _selectedExampleOrRelatedItemTestVM = null;
    public LanguageItemViewModel SelectedExampleOrRelatedItemTestVM
    {
        get { return _selectedExampleOrRelatedItemTestVM; }
        set
        {
            if (_selectedExampleOrRelatedItemTestVM != value)
            {
                Mediator.EventMediator.Instance.PassLanguageItemAsExampleOrRelatedItem(value);
                _selectedExampleOrRelatedItemTestVM = null;
                RaisePropertyChanged("SelectedExampleOrRelatedItemTestVM");
            }
        }
    }

这样,在相关事件被触发后,变量本身就被设置为 null。这也行不通。

也许有人提出了一些建议,甚至是一些我没有考虑过的途径?谢谢。

【问题讨论】:

  • 这听起来像是 UI 设计的缺陷。

标签: c# wpf listbox


【解决方案1】:

我想出了两个选择:

1) 将 ListBox.SelectedItem 与 ViewModel 的绑定设置为 OneWay 绑定,以避免在将 ViewModel 的属性设置为 null 时提到的无限循环。但由于它可能不是您想要的,并且您可能需要通过 ViewModel 更改 SelectedItem,所以第二种方法会派上用场。

2) 当用户点击 ListBox 时调用 ViewModel 的 方法,并发送 SelectedItem 作为参数。比如:

XAML

<Window>
    ...
    <ListBox x:Name="ListBoxFirst" MouseUp="ListBox_OnMouseUp"/>
    ...
</Window>

在您的 View 的 CodeBehind 文件中:

private void ListBox_OnMouseUp(object sender, MouseButtonEventArgs e)
{
    var viewModel = DataContext as YourViewModelType;

    if (viewModel != null && ListBoxFirst.SelectedItem != null)
    {
        viewModel.YourImplementedMethod(ListBoxFirst.SelectedItem);
    }
}

这样每次用户再次点击item时,都会重复调用该方法。

此外,您还可以通过 BlendSDK 库的帮助直接从您的 XAML 文件中调用该方法:

已编辑的 XAML

<Window xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity">
    ...
    <ListBox x:Name="ListBoxFirst">

        <i:Interaction.Triggers>

            <i:EventTrigger EventName="MouseUp" SourceName="ListBoxFirst">
                <i:InvokeCommandAction Command="{Binding YourViewModelCommand}"
                 CommandParameter="{Binding ElementName=ListBoxFirst, Path=SelectedItem}"/>
            </i:EventTrigger>

        </i:Interaction.Triggers>

    </ListBox>
    ...
</Window>

Interactivity 命名空间所在的位置:

System.Windows.Interactivity

祝你好运:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多