我想要实现以下目标: 我想要一个显示可用 COM 端口的组合框。启动时(并单击“刷新”按钮),我想获取可用的 COM 端口并将选择设置为最后选择的值(从应用程序设置中)。
如果设置中的值(最后一个 com 端口)不在值列表(可用 COM 端口)中,则会发生以下情况:
尽管 ComboBox 不显示任何内容(它“足够聪明”知道新的 SelectedItem 不在 ItemsSource 中),但 ViewModel 会使用“无效值”进行更新。我实际上期望 Binding 具有与 ComboBox 显示的相同的值。
用于演示目的的代码:
主窗口.xaml:
<Window x:Class="DemoComboBinding.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"
xmlns:local="clr-namespace:DemoComboBinding">
<Window.Resources>
<local:DemoViewModel x:Key="vm" />
</Window.Resources>
<StackPanel Orientation="Vertical">
<ComboBox SelectedItem="{Binding Source={StaticResource vm}, Path=Selected}" x:Name="combo"
ItemsSource="{Binding Source={StaticResource vm}, Path=Source}"/>
<Button Click="Button_Click">Set different</Button> <!-- would be refresh button -->
<Label Content="{Binding Source={StaticResource vm}, Path=Selected}"/> <!-- shows the value from the view model -->
</StackPanel>
</Window>
MainWindow.xaml.cs:
// usings removed
namespace DemoComboBinding
{
public partial class MainWindow : Window
{
//...
private void Button_Click(object sender, RoutedEventArgs e)
{
combo.SelectedItem = "COM4"; // would be setting from Properties
}
}
}
视图模型:
namespace DemoComboBinding
{
class DemoViewModel : INotifyPropertyChanged
{
string selected;
string[] source = { "COM1", "COM2", "COM3" };
public string[] Source
{
get { return source; }
set { source = value; }
}
public string Selected
{
get { return selected; }
set {
if(selected != value)
{
selected = value;
OnpropertyChanged("Selected");
}
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
void OnpropertyChanged(string propertyname)
{
var handler = PropertyChanged;
if(handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyname));
}
}
#endregion
}
}
我最初提出的一个解决方案是在 Selected setter 内部检查要设置的值是否在可用 COM 端口列表内(如果不是,则设置为空字符串并发送 OPC)。
我想知道的是:
为什么会发生这种情况?
还有其他我没有看到的解决方案吗?