C# WPF MVVM-单击时更新下拉列表
我有一个下拉列表(C# WPF MVVM-单击时更新下拉列表,c#,wpf,drop-down-menu,combobox,C#,Wpf,Drop Down Menu,Combobox,我有一个下拉列表(组合框),显示机器上所有可用的com端口。现在,当您连接和断开设备时,端口来来去去去 出于性能原因,我不想继续调用System.IO.Ports.SerialPort.GetPortNames(),而是在用户单击组合框时调用它?这可能吗?有没有一种MVVM方法可以解决这个问题?您可以使用类似MVVMLight的EventToCommand之类的工具来实现这一点。基本上,单击组合的事件将连接到MVVM命令绑定,然后该绑定将触发调用GetPortNames()的方法 以下是一些备选
组合框
),显示机器上所有可用的com端口。现在,当您连接和断开设备时,端口来来去去去
出于性能原因,我不想继续调用
System.IO.Ports.SerialPort.GetPortNames()
,而是在用户单击组合框时调用它?这可能吗?有没有一种MVVM方法可以解决这个问题?您可以使用类似MVVMLight的EventToCommand之类的工具来实现这一点。基本上,单击组合的事件将连接到MVVM命令绑定,然后该绑定将触发调用GetPortNames()的方法
以下是一些备选方案:
(检查已接受的答案)
(Prism)我的建议是放弃“点击时仅更新”的想法,只需为此使用绑定和通知(除非出于某种原因,您认为会有太多连接/断开连接事件,这会降低系统的速度)。最简单的版本是依赖属性 在ViewModel上提供一个
IObservableList
属性作为依赖属性,如下所示:
/// <summary>
/// Gets or sets...
/// </summary>
public IObservableList<Port> Ports
{
get { return (IObservableList<Port>)GetValue(PortsProperty); }
set { SetValue(PortsProperty, value); }
}
public static readonly DependencyProperty PortsProperty = DependencyProperty.Register("Ports", typeof(IObservableList<Port>), typeof(MyViewModelClass), new PropertyMetadata(new ObservableList<Port>));
//
///获取或设置。。。
///
公共IObservableList端口
{
获取{return(IObservableList)GetValue(PortsProperty);}
set{SetValue(PortsProperty,value);}
}
public static readonly dependencProperty PortsProperty=dependencProperty.Register(“端口”、typeof(IObservableList)、typeof(MyViewModelClass)、new PropertyMetadata(new ObservableList));
现在,无论何时连接或断开设备,您都可以在该列表中添加/删除项目,但不要替换该列表。这将强制列表为列表上的每个操作发送一个ListChangedEvent
,组合框(或任何其他绑定的UI)将对这些事件做出反应
这对您来说应该足够了,因为这只会导致UI组合框在事件发生时更新。我尝试将事件路由到命令: XAML:
使用
InvokeCommandAction
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
DropDownOpenedCommand是ViewModel上的ICommand
属性
<ComboBox>
<i:Interaction.Triggers>
<i:EventTrigger EventName="DropDownOpened">
<i:InvokeCommandAction Command="{Binding DropDownOpenedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
编辑:显然,正如Patrice所评论的,DropdownOpen没有选择更改。处理
DropdownOpen
事件,并在处理程序中调用GetPortsNames
,以更新项目。使用MVVM,您可以使用某种命令执行相同的操作,然后相应地更新ViewModel中的数据。请确保在属性更改时注销事件,以防止内存泄漏。我做了几乎相同的事情,但只是因为InvokeCommandAction不支持传递EventArgs——如果您不需要这样做,我认为InvokeCommandAction要容易得多(参见我的答案)。我喜欢这个--必须出去获取NuGet软件包System.Windows.Interactivity v4.0 for WPF
,它才能工作。对于在Dot Net Core 3.1中尝试这样做的任何人,快速更新:根据这个答案,System.Windows.Interactivity与Dot Net Core不兼容,但Microsoft.Xaml.Behaviors.WPF提供了所有相同的功能。IMHO,OP关注的性能不是UI更新,而是频繁调用System.IO.Ports.SerialPort.GetPortNames()
。
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
<ComboBox>
<i:Interaction.Triggers>
<i:EventTrigger EventName="DropDownOpened">
<i:InvokeCommandAction Command="{Binding DropDownOpenedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>