【发布时间】:2017-06-21 13:00:32
【问题描述】:
我有这个组合框:
<ComboBox Grid.Column="1" SelectedItem="{Binding SelectedItem}" ItemsSource="{Binding Items, Mode=OneWay}" HorizontalAlignment="Stretch" VerticalAlignment="Center"/>
这是代码:
public class CustomComboBoxViewModel
{
private bool DiscardSelChanged { get; set; }
public ObservableCollection<string> Items { get; set; }
public string SelectedItem
{
get { return _selectedItem; }
set
{
if (!DiscardSelChanged)
_selectedItem = value;
bool old = DiscardSelChanged;
DiscardSelChanged = false;
if (!old)
SelectionChanged?.Invoke(_selectedItem);
}
}
public event Action<string> SelectionChanged;
public void AddItem(string item)
{
var v = Items.Where(x => x.Equals(item)).FirstOrDefault();
if (v != default(string))
{
SelectedItem = v;
}
else
{
DiscardSelChanged = true;
_selectedItem = item;
Items.Insert(0, item);
}
}
}
在启动时我只有一项:Browse...。选择它我可以浏览文件并将其路径添加到组合框。 AddItem 方法被调用
如果所选文件路径在 Items 中不存在,我添加并选择它(这是有效的)。
如果所选文件路径存在于 Items 中,我想自动选择它而不将其再次添加到列表中。这不起作用,Browse... 是可视化项目。
我已经尝试过使用 INotifyPropertyChanged。
我正在使用 .NET 4.6.2。有什么想法让它工作吗?
编辑4:准系统示例
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows;
namespace WpfApp2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
Items = new ObservableCollection<string>();
Items.Add(ASD);
}
private string ASD = @"BROWSE";
private string _selectedItem;
public string SelectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
OnPropertyChanged(nameof(SelectedItem));
UploadFileSelection_SelectionChanged();
}
}
public ObservableCollection<string> Items { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
private void AddItem(string item)
{
var v = Items.Where(x => x.Equals(item)).FirstOrDefault();
if (v != default(string))
SelectedItem = v;
else
{
Items.Add(item);
SelectedItem = item;
}
}
private void UploadFileSelection_SelectionChanged()
{
if (SelectedItem == ASD)
{
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog()
{
DefaultExt = ".*",
Filter = "* Files (*.*)|*.*"
};
bool? result = dlg.ShowDialog();
if (result == true)
AddItem(dlg.FileName);
}
}
}
}
组合框:
<ComboBox SelectedItem="{Binding SelectedItem}" ItemsSource="{Binding Items}"/>
尝试:
- 选择 FILE_A.txt
- 选择 FILE_B.txt
- 再次选择 FILE_A.txt
【问题讨论】:
-
“我已经尝试过使用 INotifyPropertyChanged。” -- 你做错了。向我们展示您是如何做到的,我们会帮助您解决问题。
-
OnPropertyChanged(nameof(SelectedItem))调用应该在 SelectedItem 属性设置器中,在_selectedItem = value之后 -
在名为
X的属性更改其值之后立即,您必须调用OnPropertyChanged(nameof(X))。您必须在X的set块中执行此操作,在之后给支持变量一个新值。没有例外。您必须对每个属性执行此操作,并且必须在set块中执行此操作,因此每次设置属性时都会发生此操作。这就是我们所说的“实现INotifyPropertyChanged”。 -
AddItem 中还有
_selectedItem = item。将其替换为SelectedItem = item。 -
请注意,ItemsSource Binding 上的
Mode=OneWay已经是默认设置,因此是多余的。
标签: c# wpf combobox binding selecteditem