我有一个组合框,其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”,但打开下拉列表时不应该有任何项目。
答案 0 :(得分:0)
我不知道这是否扮演任何角色,但它确实看起来很可疑。尝试删除它:
<ComboBox ... SelectedValue="Code" ...
答案 1 :(得分:0)
要保留所选项目不在列表中,您可以执行以下操作:
这些更改可能会导致您的代码弊大于利,但希望这会让您开始。
以下是代码隐藏:
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>