首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WPF ComboBox SelectedItem

WPF ComboBox SelectedItem
EN

Stack Overflow用户
提问于 2010-01-29 01:59:16
回答 7查看 13K关注 0票数 7

好的,我使用WPF已经有一段时间了,但我需要一些帮助。

我有一个如下所示的ComboBox

代码语言:javascript
复制
<TabControl>
    <TabItem Header="1">
        <ComboBox ItemsSource="{Binding MyList}" SelectedItem="{Binding MyListSelection}"/>
    </TabItem>
    <TabItem Header="2"/>
</TabControl>

每当我离开选项卡1,然后返回到它时,所选内容就会被删除。我认为这样做的原因是,当控件超出范围,然后又返回时,它们会被销毁。但在这个过程中,SelectedItem变为空,这并不是用户真正想要的,这是由于UI生命周期造成的事件。

所以我想知道最好的路线是什么?我正在用MVVM构建这个应用程序,所以我可以忽略ViewModel中MyListSelection属性上的set调用,但我到处都是ComboBoxes,我不喜欢修改我的ViewModel,因为我认为这是WPF的一个错误。

我可以子类化WPF ComboBox,但没有SelectedItemChanging事件,我只能在SelectedItem更改时添加一个处理程序。

有什么想法吗?

更新:

好了,在我把头撞到墙上之后,我发现了为什么我的问题不能重现。如果列表项类型是一个类,由于某种原因,SelectedItem会被WPF设置为null,但如果它是一个值类型,则不会。

下面是我的测试类(VMBase只是一个实现INotifyPropertyChanged的抽象类):

代码语言:javascript
复制
public class TestListViewModel : VMBase
{
    public TestListViewModel()
    {
        TestList = new List<TestViewModel>();
        for (int i = 0; i < 10; i++)
        {
            TestList.Add(new TestViewModel(i.ToString()));
        }
    }

    public List<TestViewModel> TestList { get; set; }

    TestViewModel _SelectedTest;
    public TestViewModel SelectedTest
    {
        get { return _SelectedTest; }
        set
        {
            _SelectedTest = value;
            OnPropertyChanged("SelectedTest");
        }
    }
}

public class TestViewModel : VMBase
{
  public string Name {get;set;}
}

因此,当我将TestList更改为int类型并在选项卡之间来回切换时,SelectedItem保持不变。但是当它的类型为TestViewModel时,当选项卡项失去焦点时,SelectedTest将被设置为null。

到底怎么回事?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2010-05-07 22:51:39

我也有同样的问题,直到现在我都不知道问题出在哪里。我在4台不同的机器上测试了相同的操作系统,.Net版本和硬件规格,可以在其中两台机器上重现这个问题,在另一台机器上工作得很好。我能找到的适合我的变通方法是在ItemsSource之前定义SelectedItem绑定。奇怪的是,如果我遵循这种模式,一切都会按预期运行。也就是说,您只需执行以下操作:

代码语言:javascript
复制
<Window x:Class="ComboBoxInTabItemSpike.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel>
        <TabControl>
            <TabItem Header="1">
                <ComboBox SelectedItem="{Binding MySelect}" ItemsSource="{Binding MyList}"/>
            </TabItem>
            <TabItem Header="2"/>
        </TabControl>
        <TextBlock Text="{Binding MySelect}"/>
    </StackPanel>
</Window>
票数 10
EN

Stack Overflow用户

发布于 2010-01-29 02:16:23

在操作中更改后进行编辑。嗨,何塞,我不能重现你提到的错误。所以你关于控制被摧毁的假设是错误的。使用下面的代码,Combobox的行为与预期一样,即使它现在使用了引用类型。当您更改TabItems时,您的其他代码片段必须生效。

代码语言:javascript
复制
<Window x:Class="ComboBoxInTabItemSpike.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel>
        <TabControl>
            <TabItem Header="1">
                <ComboBox ItemsSource="{Binding MyList}"
                          SelectedItem="{Binding MySelect}"/>
            </TabItem>
            <TabItem Header="2"/>
        </TabControl>
        <TextBlock Text="{Binding MySelect}"/>
    </StackPanel>
</Window>

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;

namespace ComboBoxInTabItemSpike
{
    public partial class Window1 : Window, INotifyPropertyChanged
    {
        public Window1()
        {
            InitializeComponent();
            MyList=new ObservableCollection<TestObject>(
                new[]{new TestObject("1"),new TestObject("2"),new TestObject("3") });
            DataContext = this;
        }

        public ObservableCollection<TestObject> MyList { get; set; }

        private TestObject mySelect;
        public TestObject MySelect
        {
            get { return mySelect; }
            set{ mySelect = value;
            if(PropertyChanged!=null)
                PropertyChanged(this,new PropertyChangedEventArgs("MySelect"));} 
        }

        public TestObject MySelectedItem
        {
            get { return (TestObject)GetValue(MySelectedItemProperty); }
            set { SetValue(MySelectedItemProperty, value); }
        }

        public static readonly DependencyProperty MySelectedItemProperty =
            DependencyProperty.Register("MySelectedItem",
                                typeof(TestObject),
                                typeof(Window1),
                                new UIPropertyMetadata(null));

        public event PropertyChangedEventHandler PropertyChanged;
    }

    public class TestObject
    {
        public string Name { get; set; }

        public TestObject(string name)
        {
            Name = name;
        }

        public override string ToString()
        {
            return Name;
        }
    }
}
票数 0
EN

Stack Overflow用户

发布于 2010-01-29 02:28:02

我建议您检查绑定。如果应用程序中的任何其他内容正在更改所选项目或项目源,那么您的绑定将会断开。您还可以在Visual Studio的“输出”窗口中查看是否有任何错误。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2156705

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档