c# - 视图更改后绑定的 ComboBoxItem 变量变为空
问题描述
我有一个问题,我正在寻找一个解释。它类似于WPF ComboBox SelectedItem Set to Null on TabControl Switch中讨论的内容,但它涉及的绑定程度较低,因此应该对更简单的解决方案开放。我在下面描述的是我构建的一个简化案例,用于重现并尝试了解问题出现的原因。
因此,该项目是基于 MVVM 的,主窗口只有一个标有“搜索”的按钮,声明如下:
<Button Margin="50,0,0,0" Width="150" Height="40" Content="Search" HorizontalAlignment="Left" Command="{Binding UpdateViewCommand}" CommandParameter="Search"/>
代码绑定到 UpdateView :ICommand ,定义如下:
class UpdateViewCommand : ICommand
{
private MainViewModel viewModel;
public UpdateViewCommand(MainViewModel viewModel)
{
this.viewModel = viewModel;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
if (parameter.ToString() == "Search")
{
viewModel.SelectedViewModel = new SearchViewModel();
}
}
}
此视图与上部的主视图重叠,“搜索”按钮可见,如下图所示:
该视图包括一个 ComboBox 和一个“Go”按钮,声明为:
<ComboBox Name="SearchCriterion" Canvas.Left="128" Canvas.Top="14" Height="22" Width="257" Background="#FF66CCFF" BorderBrush="Black" SelectedIndex="0"
SelectedItem="{Binding QueryType, Mode=OneWayToSource}">
<ComboBoxItem FontFamily="Calibri" FontSize="14" Background="#FF66CCFF">
Author
</ComboBoxItem>
<ComboBoxItem FontFamily="Calibri" FontSize="14" Background="#FF66CCFF">
Title
</ComboBoxItem>
</ComboBox>
<Button Name="SearchButton" Height="22" Content="Go" Canvas.Left="390" Canvas.Top="44" Width="45" BorderBrush="Black"
FontFamily="Calibri" FontSize="14" Background="#FF0066FF" Command="{Binding ExecQueryCmd}" Foreground="White"/>
该按钮所做的就是通过变量 QueryType 获取 ComboBox 声明中绑定的 ComboBoxItem 值并打印它。QueryType 声明为:
private ComboBoxItem _queryType = new ComboBoxItem();
public ComboBoxItem QueryType
{
get { return _queryType; }
set
{
Globals.mylog.Trace("In SearchViewModel.QueryType");
_queryType = value;
OnPropertyChanged(nameof(QueryType));
}
}
假设这很清楚,这就是我看到的问题。我启动程序,单击“搜索”并出现 SearchView。我玩组合框,单击“开始”,一切都很好。我可以多次这样做,没有问题。
现在我再次点击“搜索”。没有明显的变化(视图已经存在),但是如果我单击“Go”,则会引发异常,因为变量为空(我在 Visual Studio 下运行,所以我可以轻松检查)。请注意,如果不是在单击“搜索”后立即单击“执行”,而是单击 ComboxBox 并在之前更改其值,则一切正常。
谁能解释我为什么会发生这种情况,以及我该如何解决?
谢谢
解决方案
您从未在 QueryType 的构造函数中显式地为 QueryType 赋值SearchViewModel
,因此 querytype 中的值取决于 UI 来更新它。一个更好的方法是让 selectedvalue 来自视图模型(并且没有我在评论中提到的游览视图模型中的 ui 元素)。
我所做的改变使它工作:在SearchViewModel
:
/// <summary>
/// Selected option to search by (it is now a string)
/// </summary>
private string _queryType;
public string QueryType
{
get { return _queryType; }
set
{
Globals.mylog.Trace("In SearchViewModel.QueryType");
_queryType = value;
OnPropertyChanged(nameof(QueryType));
}
}
/// <summary>
/// List of options to search by
/// </summary>
public ObservableCollection<string> Queries { get; set; }
public SearchViewModel()
{
Globals.mylog.Trace("In SearchViewModel");
//Initialization ofthe list of options
Queries = new ObservableCollection<string> { "Author", "Title" };
//Initialization of the selected item
this.QueryType = Queries.FirstOrDefault();
ExecQueryCmd = new RelayCommand(ExecuteQuery, CanExecuteQuery);
}
在搜索视图中:
<--The combobox is now bound to the list in the ViewModel(the data is stored in the viewmodels and the view is only responsible for displaying it) -->
<Canvas Width="517" Height="580" Background="#FFCCFF99">
<ComboBox Name="SearchCriterion" Canvas.Left="128" Canvas.Top="14" Height="22" Width="257" ItemsSource="{Binding Queries}" Background="#FF66CCFF" BorderBrush="Black"
SelectedItem="{Binding QueryType, Mode=TwoWay}">
<ComboBox.ItemContainerStyle>
<Style BasedOn="{StaticResource {x:Type ComboBoxItem}}" TargetType="{x:Type ComboBoxItem}">
<Setter Property="FontFamily" Value="Calibri"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Background" Value="#FF66CCFF"/>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
<Button Name="SearchButton" Height="22" Content="Go" Canvas.Left="390" Canvas.Top="44" Width="45" BorderBrush="Black"
FontFamily="Calibri" FontSize="14" Background="#FF0066FF" Command="{Binding ExecQueryCmd}" Foreground="White"/>
</Canvas>
推荐阅读
- javascript - 如何在“Google Chrome 控制台内部”循环延迟 1 秒
- python - 是否可以直接使用类型提示验证?
- c# - 我的代码有什么问题吗,因为它在数据库中保存了相同的数据,即使扫描了不同的指纹?
- python - Django 从 postgresql 数据库填充的下拉菜单的完整示例
- vb.net - 无法关闭我的 MS Access 数据库的 OleDbDataReader
- angularjs - 如何使用角度获取从输入类型文件到 img src 的图像路径
- .htaccess - 当我打开像 www.domain.com 这样的域时,它会重定向到 www.www.domain.com
- python - 复制然后粘贴在python终端mac中产生垃圾
- javascript - 从表中获取数据以显示为纯文本
- php - 有没有办法连接 1 行唯一键并在表单中显示其数据?