【问题标题】:WPF Single selection between two ListBoxesWPF 两个列表框之间的单选
【发布时间】:2013-01-11 11:11:38
【问题描述】:

我遇到以下问题:我有两个ListBox,有两个不同的ItemSource,但对于SelectedItem,它们都有相同的binding,因为我试图执行单个选择在这两个列表之间。

这是一张更能说明问题的图片:

我想做什么?每次我从第一个列表(红色)中选择一个项目时,它应该取消选择第二个列表(黑色)中的SelectedItem,反之亦然。这就是为什么我对他们两个都使用相同的binding。 我真的不知道这是否是更好的方法,但它应该像那样工作。

你能帮帮我吗?

【问题讨论】:

  • 我认为您应该改用自定义附加行为...
  • @FelicePollano 但我该怎么做呢?你有一些代码可以帮忙吗?
  • 这和stackoverflow.com/questions/4293253/…这样的问题有关
  • @dowhilefor 我会检查这个问题,看看它是否有效。
  • @Clemens 类型是“版本”,我的自定义类之一。

标签: c# wpf visual-studio-2010 mvvm listbox


【解决方案1】:

尝试改用SelectedValue,这会影响您所看到的行为

 <ListBox SelectedValue="{Binding MySelectedItem}" />

SelectedItem似乎没有取消选择是在列表中没有找到所选项目,但是SelectedValue似乎确实取消了选择它,不知道为什么

您可以在此示例应用中看到差异:

xaml:

<Window x:Class="WpfApplication11.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="184" Width="208" x:Name="UI">
    <StackPanel DataContext="{Binding ElementName=UI}">
        <TextBlock Text="SelectedValue" />
        <StackPanel Orientation="Horizontal" Height="60" >
            <ListBox ItemsSource="{Binding MyItemSource1}" SelectedValue="{Binding MySelectedValue}" Width="100" />
            <ListBox ItemsSource="{Binding MyItemSource2}" SelectedValue="{Binding MySelectedValue}" Width="100" />
        </StackPanel>
        <TextBlock Text="SelectedItem" />
        <StackPanel Orientation="Horizontal" Height="60"  >
            <ListBox ItemsSource="{Binding MyItemSource1}" SelectedItem="{Binding MySelectedItem}" Width="100" />
            <ListBox ItemsSource="{Binding MyItemSource2}" SelectedItem="{Binding MySelectedItem}" Width="100" />
        </StackPanel>
    </StackPanel>
</Window>

代码:

public partial class MainWindow : Window , INotifyPropertyChanged
{
    private CustomObject _mySelectedItem;
    private CustomObject _mySelectedValue;
    private ObservableCollection<CustomObject> _items = new ObservableCollection<CustomObject>();
    private ObservableCollection<CustomObject> _items2 = new ObservableCollection<CustomObject>();

    public MainWindow()
    {
        InitializeComponent();
        MyItemSource1.Add(new CustomObject { Name = "Stack" });
        MyItemSource1.Add(new CustomObject { Name = "Overflow" });
        MyItemSource2.Add(new CustomObject { Name = "Stack" });
        MyItemSource2.Add(new CustomObject { Name = "Overflow" });
    }

    public ObservableCollection<CustomObject> MyItemSource1
    {
        get { return _items; }
        set { _items = value; }
    }

    public ObservableCollection<CustomObject> MyItemSource2
    {
        get { return _items2; }
        set { _items2 = value; }
    }

    public CustomObject MySelectedItem
    {
        get { return _mySelectedItem; }
        set { _mySelectedItem = value; NotifyPropertyChanged("MySelectedItem"); }
    }

    public CustomObject MySelectedValue
    {
        get { return _mySelectedValue; }
        set { _mySelectedValue = value; NotifyPropertyChanged("MySelectedValue"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
}

public class CustomObject
{
    public string Name { get; set; }
    public override string ToString()
    {
        return Name;
    }
}

【讨论】:

  • 我尝试使用SelectedValue,但没有成功。我认为这是因为我在property's set 中调用了另一个需要不同于null 的值的方法,如果我使用SelectedValue,它会以某种方式尝试将null 设置为我的属性。我不知道我是否清楚这个评论。
  • 这行得通,但现在我开始思考为什么我需要 SelectedItem 呢?!
【解决方案2】:

我要做的是首先将null 传递给属性并通知更改,然后将实际值传递给属性并通知视图更改。 像这样:

protected Bar selectedItem;
public Bar SelectedItem{
    get
    {
        return selectedItem;
    }
    set
    {
        selectedItem = null;
        NotifyPropertyChanged("SelectedItem");

        selectedItem = value;
        NotifyPropertyChanged("SelectedItem");
    }

我从this question 得到这个答案和例子。

【讨论】:

  • 这个修复效果很好。简单但有效。我能想到的唯一可能出错的事情是,当另一个线程尝试在 SelectedItem 设置为 null 时访问它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-17
  • 2022-11-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多