ComboBox SelectedIndex 绑定 -1 或 0 不选择第一项
Posted
技术标签:
【中文标题】ComboBox SelectedIndex 绑定 -1 或 0 不选择第一项【英文标题】:ComboBox SelectedIndex Binding -1 or 0 not selecting first item 【发布时间】:2021-04-01 00:35:13 【问题描述】:我有一个ComboBox
,它会在SelectedItem
更改时写入配置文件。
我想使用SelectedIndex = -1
作为备用,以防SelectedItem
丢失。
我不希望SelectedIndex
在程序启动时触发并写入配置文件,所以我将事件处理程序放在C#
Window_Loaded()
而不是XAML
。
问题是Video_SelectedIndex = -1
没有选择任何内容,它使SelectedItem
留空。
主窗口
private void Window_Loaded(object sender, RoutedEventArgs e)
cboPlugin_Video.SelectedIndex += VM.PluginsView.Video_SelectedIndex; // <-- Problem here
cboPlugin_Video.SelectionChanged += cboPlugin_Video_SelectionChanged;
我试图以另一种方式绑定它,但它在程序启动时触发。
cboPlugin_Video.DataContext = VM.PluginsView;
Binding Plugins_Video_SelectedIndexBinding = new Binding() Source = VM.PluginsView, Path = new PropertyPath("Video_SelectedIndex"), Mode = BindingMode.TwoWay ;
cboPlugin_Video.SetBinding(ComboBox.SelectedIndexProperty, Plugins_Video_SelectedIndexBinding);
XAML
<Window.DataContext>
<local:VM/>
</Window.DataContext>
<ComboBox x:Name="cboPlugin_Video"
DataContext="Binding PluginsView"
ItemsSource="Binding Video_Items"
SelectedItem="Binding Video_SelectedItem"
Margin="10,12,0,0"
VerticalAlignment="Top"
Height="22"
HorizontalAlignment="Left"
Width="140" />
视图模型
namespace ViewModel
public class PluginsViewModel : INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged = delegate ;
private void OnPropertyChanged(string prop)
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(prop));
private int _Video_SelectedIndex get; set;
public int Video_SelectedIndex
get return _Video_SelectedIndex;
set
if (_Video_SelectedIndex == value)
return;
_Video_SelectedIndex = value;
OnPropertyChanged("Video_SelectedIndex");
选择项目/索引
// Plugin Found
if (test == "Example")
VM.PluginsView.Video_SelectedItem = "Example"; // Works
// Missing, Default to First Item
else
VM.PluginsView.Video_SelectedIndex = -1; // <-- Not working
选择更改事件
private void cboPlugin_Video_SelectionChanged(object sender, SelectionChangedEventArgs e)
// Write to config file
// Works
【问题讨论】:
The problem is Video_SelectedIndex = -1 doesn't select anything, it leaves the SelectedItem blank.
有错字吗? cboPlugin_Video.SelectedIndex += VM.PluginsView.Video_SelectedIndex;
- 不应该只是=
而不是+=
吗?
@RandRandom 它看起来像 +=
和 -1
而不是 0
是问题所在,但在将其更改为 =
后,它现在在启动时触发。
@RandRandom 我认为我不能正确地将它绑定到 ViewModel。我想我必须将MainWindow
传递给它并使用mainwindow.cboPlugin_Video.SelectedIndex = 0
您可以在ContentRendered
上注册SelectionChanged
事件而不是加载docs.microsoft.com/en-us/dotnet/api/… - 这应该在所有绑定评估后发生
【参考方案1】:
期待评论
你为什么不在你的 setter 中写配置?
private int _Video_SelectedIndex get; set;
public int Video_SelectedIndex
get return _Video_SelectedIndex;
set
if (_Video_SelectedIndex == value)
return;
_Video_SelectedIndex = value;
OnPropertyChanged("Video_SelectedIndex");
//write to config
这样您就不会将SelectionChange
从无 (-1) 变为 0,因为 _Video_SelectedIndex
将使用 0 进行初始化,如果 if (_Video_SelectedIndex == value)
从 0
更改为 @987654326 将阻止触发@。
顺便说一句,您为什么将_Video_SelectedIndex
声明为属性而不是字段?
为什么会这样:
private int _Video_SelectedIndex get; set;
而不是
private int _Video_SelectedIndex;
编辑:
我无法重现你的问题,也许我做的这个小测试项目会对你有所帮助。
如果不是,请进行必要的更改以显示您的问题。
注意,我已经测试了SelectedIndex
和SelectedItem
。
MainWindow.xaml
<Window x:Class="WpfApp10.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp10">
<Window.DataContext>
<local:MyViewModel />
</Window.DataContext>
<StackPanel Orientation="Vertical">
<TextBlock Text="ComboBox with SelectedItem" />
<ComboBox ItemsSource="Binding Items" SelectedItem="Binding SelectedItem" />
<TextBlock Text="ComboBox with SelectedIndex" />
<ComboBox ItemsSource="Binding Items" SelectedIndex="Binding SelectedIndex" />
</StackPanel>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
public MainWindow()
InitializeComponent();
MyViewModel.cs
public class MyViewModel : INotifyPropertyChanged
private Config _config;
private string _selectedItem;
private int _selectedIndex;
public event PropertyChangedEventHandler? PropertyChanged;
public IEnumerable<string> Items get; set; = Enumerable.Range(0, 10).Select(x => $"Foo x");
public string SelectedItem
get => _selectedItem;
set
if (_selectedItem == value)
return;
_selectedItem = value;
OnPropertyChanged();
//write config
_config.SelectedItem = value;
public int SelectedIndex
get => _selectedIndex;
set
if (_selectedIndex == value)
return;
_selectedIndex = value;
OnPropertyChanged();
//write config
_config.SelectedIndex = value;
public MyViewModel()
_config = new Config();
//read config
_selectedItem = _config.SelectedItem;
_selectedIndex = _config.SelectedIndex;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
Config.cs
public class Config
public string SelectedItem get; set;
public int SelectedIndex get; set;
public Config()
//fake reading stuff from *.config file
//test it with either of those
//SelectedItem = "Foo 2";
//SelectedIndex = 2;
SelectedItem = null;
SelectedIndex = -1;
//write config
两个部分仅在用户手动更改组合框值时才会命中,而不是在启动时自动命中。
如果配置返回null
或-1
,要使用默认值,您可以更改此代码:
//read config
_selectedItem = _config.SelectedItem;
_selectedIndex = _config.SelectedIndex;
到这里:
//read config
_selectedItem = _config.SelectedItem ?? Items.First();
_selectedIndex = _config.SelectedIndex == -1 ? 0 : _config.SelectedIndex;
或者要准确检查存储在_config
中的值是否仍然有效,您可以使用它
_selectedItem = Items.Contains(_config.SelectedItem) ? _config.SelectedItem : Items.First();
_selectedIndex = _config.SelectedIndex >= Items.Count() || _config.SelectedIndex < 0 ? 0 : _config.SelectedIndex;
【讨论】:
我尝试在设置器中写入配置,但绑定SelectedIndex
仍然在启动时触发,我尝试了任何方式。 get; set;
可能是我所关注的示例中的意外。
@MattMcManis - 你的问题解决了吗?【参考方案2】:
值 -1 表示没有选择任何元素。您必须将其设置为 0 才能获得第一项。
如此处所述:
https://docs.microsoft.com/de-de/dotnet/api/system.windows.forms.combobox.selectedindex?view=net-5.0
【讨论】:
以上是关于ComboBox SelectedIndex 绑定 -1 或 0 不选择第一项的主要内容,如果未能解决你的问题,请参考以下文章
datatable绑定comboBox,在下拉菜单中显示对应数据
C# 如果获得combobox的下拉表中有多少项(Items)