将ComboBox Selected Item设置为ItemSsource中不存在的dataobject

时间:2011-03-20 23:46:26

标签: wpf combobox selecteditem

我有一个组合框,其SelectedItem和ItemSource属性绑定到viewmodel。 ItemSource中的对象是时间敏感的,因为对象过期,我只能将集合中的活动项设置为ItemSource。现在在某一点上,selectedItem对象可能不在ItemSource中。 我认为ItemSource的正常行为是只允许从ItemSource Collection中选择对象,但在这种情况下我想要选择一个不再在ItemSource中的对象。 我该如何实现这种行为?我会在这里发布一些代码来支持我的问题。

Window.xaml

 <Window x:Class="ExpiredSelectedItem.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <ComboBox Height="23" 
              HorizontalAlignment="Left" 
              Margin="184,68,0,0" 
              Name="comboBox1" 
              VerticalAlignment="Top" 
              Width="120" 
              ItemsSource="{Binding CustomList}"
              SelectedItem="{Binding ActiveItem}"
              SelectedValue="Code"
              SelectedValuePath="{Binding ActiveItem.Code}"
              DisplayMemberPath="Code"
              />
</Grid>

Window.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ExpiredSelectedItem
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        CustomList = new List<DomainObject>();

        CustomList.AddRange(new DomainObject[] {
            new DomainObject() { Code = "A", IsActive =true},
            new DomainObject() { Code ="B", IsActive = true},
            new DomainObject() { Code = "C", IsActive =true},
        });

        ActiveItem = new DomainObject() { Code = "D", IsActive = false };

        this.DataContext = this;
    }


    public List<DomainObject> CustomList { get; set; }

    public DomainObject ActiveItem { get; set; }
}

public class DomainObject
{
    public string Code { get; set; }
    public bool IsActive { get; set; }

}

}

即使我在代码隐藏中选择代码D,当组合框加载时,选择第一个项目(A)。预期的行为是应该在文本框中选择“D”,但打开下拉列表时不应该有任何项目。

2 个答案:

答案 0 :(得分:0)

我不知道这是否扮演任何角色,但它确实看起来很可疑。尝试删除它:

<ComboBox ... SelectedValue="Code" ...

答案 1 :(得分:0)

要保留所选项目不在列表中,您可以执行以下操作:

  • 防止ActiveItem设置为NULL;见:if(value!= null)
  • 清除ComboBox;请参阅:comboBox1.SelectedIndex = -1;
  • 实施INotifyPropertyChanged(您可能已经这样做了)

这些更改可能会导致您的代码弊大于利,但希望这会让您开始。

以下是代码隐藏:

using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;

namespace ComboBoxSelectedItem
{
  public partial class MainWindow : Window, INotifyPropertyChanged
  {
    public event PropertyChangedEventHandler PropertyChanged;
    void Notify(string propName)
    {
      if (PropertyChanged != null)
      {
        PropertyChanged(this, new PropertyChangedEventArgs(propName));
      }
    }

    public MainWindow()
    {
      InitializeComponent();

      CustomList = new List<DomainObject>();

      CustomList.AddRange(new DomainObject[] {
        new DomainObject() { Code = "A", IsActive =true},
        new DomainObject() { Code ="B", IsActive = true},
        new DomainObject() { Code = "C", IsActive =true},
        });

      this.DataContext = this;
    }

    public List<DomainObject> CustomList { get; set; }

    private DomainObject _activeItem = new DomainObject() { Code = "D", IsActive = false };
    public DomainObject ActiveItem 
    {
      get { return _activeItem; }
      set
      {
        if (value != null)
        {
          _activeItem = value;
        }

        Notify("ActiveItem");
      }
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
      ActiveItem = new DomainObject() { Code = "D", IsActive = false };
      comboBox1.SelectedIndex = -1;
    }
  }
}

这是XAML:

<Window x:Class="ComboBoxSelectedItem.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
  <Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <ComboBox 
        Grid.Row="0"
        Height="23" 
        HorizontalAlignment="Left" 
        Name="comboBox1" 
        VerticalAlignment="Top" 
        Width="120" 
        ItemsSource="{Binding CustomList}"
        SelectedItem="{Binding ActiveItem}"
        DisplayMemberPath="Code"/>
    <TextBox 
        Grid.Row="1"
        Text="{Binding Path=ActiveItem.Code, Mode=TwoWay}"/>
    <Button 
        Grid.Row="2" 
        Content="D" 
        Click="Button_Click"/>
  </Grid>
</Window>