C# 组合框已选择索引绑定-1或0未选择第一项
我有一个组合框,当SelectedItem被更改时,它会写入配置文件。 我想使用SelectedIndex=-1作为备用,以防SelectedItem丢失 我不希望SelectedIndex在程序启动时触发并写入配置文件,所以我将事件处理程序放在C窗口中,而不是XAML 问题是Video_SelectedIndex=-1没有选择任何内容,它会将SelectedItem留空 主窗口 XAML 选择项目/索引C# 组合框已选择索引绑定-1或0未选择第一项,c#,wpf,xaml,combobox,C#,Wpf,Xaml,Combobox,我有一个组合框,当SelectedItem被更改时,它会写入配置文件。 我想使用SelectedIndex=-1作为备用,以防SelectedItem丢失 我不希望SelectedIndex在程序启动时触发并写入配置文件,所以我将事件处理程序放在C窗口中,而不是XAML 问题是Video_SelectedIndex=-1没有选择任何内容,它会将SelectedItem留空 主窗口 XAML 选择项目/索引 值-1表示未选择任何元素。必须将其设置为0才能获取第一项 如下所述: 垂涎三尺 为什么不在
值-1表示未选择任何元素。必须将其设置为0才能获取第一项 如下所述: 垂涎三尺 为什么不在setter中写入config
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从nothing-1到0,因为_Video_SelectedIndex将被初始化为0,如果_Video_SelectedIndex==值从0变为0,则将阻止触发
作为补充说明,为什么您将_Video_SelectedIndex声明为属性而不是字段
那么,为什么会这样:
private int _Video_SelectedIndex { get; set; }
而不是
private int _Video_SelectedIndex;
编辑:
我不能重现你的问题,也许我做的这个小测试项目会帮助你
如果没有,请进行必要的更改以显示您的问题
注意,我已经测试了SelectedIndex和SelectedItem
MainWindow.xaml
MyViewModel.cs
只有当用户手动更改combox值时,才会命中//写入配置部分,而不会在启动时自动命中
要在配置返回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;
问题是Video_SelectedIndex=-1没有选择任何内容,它会将SelectedItem留空。有打字错误吗?cboPlugin\u Video.SelectedIndex+=VM.pluginView.Video\u SelectedIndex;-它不应该只是=而不是+=?@RandRandom问题看起来是+=和-1而不是0,但是在将其更改为=,它现在在启动时启动。@RandRandRandom我认为我无法将其正确绑定到ViewModel。我想我必须将主窗口传递给它,并使用MainWindow.cboPlugin\u Video.SelectedIndex=0您可以在ContentRendered而不是loaded上注册SelectionChanged事件-这应该发生在所有已评估的绑定之后我尝试在setter中写入配置,但binding SelectedIndex在启动时仍会以任何方式启动。{get;set;}很可能是我所遵循的一个例子中的意外事件。@mattmcanis-看看我的edit@MattMcManis-你的问题解决了吗?
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
}
}
private int _Video_SelectedIndex { get; set; }
private int _Video_SelectedIndex;
<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>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
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));
}
}
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;
}
}
//read config
_selectedItem = _config.SelectedItem;
_selectedIndex = _config.SelectedIndex;
//read config
_selectedItem = _config.SelectedItem ?? Items.First();
_selectedIndex = _config.SelectedIndex == -1 ? 0 : _config.SelectedIndex;
_selectedItem = Items.Contains(_config.SelectedItem) ? _config.SelectedItem : Items.First();
_selectedIndex = _config.SelectedIndex >= Items.Count() || _config.SelectedIndex < 0 ? 0 : _config.SelectedIndex;