关于WPF MVVM下,在线程里修改UI绑定值的安全性
mc:Ignorable="d" WindowStartupLocation="CenterScreen" Title="MainWindow" Style="{StaticResource BaseWindowStyle}">
<Window.Resources>
<ObjectDataProvider MethodName="GetValues" ObjectType="{x:Type sys:Enum}" x:Key="MyLightMode">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="api:LightMode"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ObjectDataProvider MethodName="GetValues" ObjectType="{x:Type sys:Enum}" x:Key="MySortingLogStyle">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="e:ESortingLogStyle"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<valueConverter:ChannelValueConverter x:Key="ChannelValueConverter"/>
<valueConverter:SortingLogStyleValueConverter x:Key="SortingLogStyleValueConverter"/>
</Window.Resources>
<i:Interaction.Triggers>
<prism:InteractionRequestTrigger SourceObject="{Binding ShowMessageBoxRequest}">
<utils:CustomPopupWindowAction CenterOverAssociatedObject="True" IsModal="True">
<prism:PopupWindowAction.WindowContent>
<dlg:ShowMessageUserControl/>
</prism:PopupWindowAction.WindowContent>
</utils:CustomPopupWindowAction>
</prism:InteractionRequestTrigger>
<prism:InteractionRequestTrigger SourceObject="{Binding ProcessSortingUIRequest}">
<ta:ProcessSortingUITriggerAction/>
</prism:InteractionRequestTrigger>
</i:Interaction.Triggers>
<Grid>
<Viewbox Stretch="Fill" >
<Canvas Height="648" Width="1024">
<Label Content="{Binding CurrentErrorInfo}" Canvas.Top="597" Background="Red" Foreground="White" Width="1013" Height="36">
<Label.Style>
<Style TargetType="{x:Type Label}" BasedOn="{StaticResource ContentAlignmentLabelStyle}">
<Setter Property="Padding" Value="3,3"/>
<Style.Triggers>
<Trigger Property="Content" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed"/>
</Trigger>
<Trigger Property="Content" Value="">
<Setter Property="Visibility" Value="Collapsed"/>
</Trigger>
</Style.Triggers>
</Style>
</Label.Style>
</Label>
</Canvas>
</TabItem>
</TabControl>
<StackPanel Visibility="{Binding AutoTagSelfCheckingProgressVisibility,UpdateSourceTrigger=PropertyChanged}" Orientation="Horizontal" Background="White" Canvas.Left="1" Canvas.Top="515" Width="1023" Height="82">
<Label Content=" 自检中..." Style="{StaticResource ContentAlignmentLabelStyle}" />
<ProgressBar Height="42" Value="{Binding AutoTagSelfCheckingProgressValue, UpdateSourceTrigger=PropertyChanged}" Width="882" Minimum="0" Maximum="100" Margin="0,20" Foreground="Blue"/>
</StackPanel>
</Canvas>
</Viewbox>
</Grid>
</base:BaseWindow>
...:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
// 是不是invoke已经可以保证线程安全了?
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
string currentErrorInfo;
public string CurrentErrorInfo
{
get
{ return currentErrorInfo; }
set
{
if (currentErrorInfo != value)
{
Interlocked.Exchange(ref currentErrorInfo, value);
OnPropertyChanged(nameof(CurrentErrorInfo));
}
}
}
object autoTagSelfCheckingProgressVisibility = Visibility.Collapsed;
public Visibility AutoTagSelfCheckingProgressVisibility
{
get
{ return (Visibility)autoTagSelfCheckingProgressVisibility; }
set
{
if ((Visibility)autoTagSelfCheckingProgressVisibility != value)
{
Interlocked.Exchange(ref autoTagSelfCheckingProgressVisibility, value);
OnPropertyChanged(nameof(AutoTagSelfCheckingProgressVisibility));
}
}
}
比如
一个是绑定改变label文字的 CurrentErrorInfo
一个是改变进度条控件显示的AutoTagSelfCheckingProgressVisibility
目前都是直接在ViewModel里某个线程里直接修改绑定值了,倒是一直也没出问题,
ThreadPool.QueueUserWorkItem(obj =>
{
CurrentErrorInfo="111";
AutoTagSelfCheckingProgressVisibility = Visibility.Visible;
});
是不是最好还是这样?:
Application.Current.Dispatcher.Invoke((Action)(()=>{
AutoTagSelfCheckingProgressVisibility = Visibility.Visible;
}));
有没有必要?为什么不用也不会出错,报跨线程处理UI的错误
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
// 是不是invoke已经可以保证线程安全了?
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
另外,绑定Visibility属性时,如何设置默认值Collapsed,否则程序启动控件会显示,直到绑定值Collapsed生效后消失
public MainWindow()
{
InitializeComponent();
this.ContentRendered += MainWindow_ContentRendered;
}
private void MainWindow_ContentRendered(object sender, EventArgs e)
{
this.DataContext = new MainViewModel();
Visibility="{Binding AutoTagSelfCheckingProgressVisibility,UpdateSourceTrigger=PropertyChanged}"
...全文
相关推荐
WPF_MVVM中DataGrid列中使用ComBox绑定
WPF之MVVM中DataGrid中嵌入Combox,改变Combox可回传至绑定的实体
WPF数据绑定实战训练课程
本文还有配套的精品资源,点击获取 简介:本课程深入探讨了WPF框架中的数据绑定技术,讲解了如何通过数据绑定实现UI元素与数据模型的直接交互,并保持视图与模型的同步。课程包含一系列代码文件,用于学习和实践数据绑定的关键步骤,如设置数据源、定义绑定表达式、处理数据转换和实时更新UI等。通过分析和操作这些文件,学习者将掌握如何在WPF应用中有效运用数据绑定技术,并理解MVVM设计...
WPF MVVM无Command属性的控件绑定事件
我们在WPF开发中应用MVVM开发模式时,一般用来绑定Button 的Command命令,但是有很多控件MS没有给出Command命令,我们需要添加一个DLL来增加绑定时的属性。
WPF纯MVVM事件绑定+事件参数 完美示例
WPF 纯MVVM模式 任意事件绑定 获取EventArgs 完美取代原生事件+=模式 只需要引用System.Windows.Interactivity
WPF 数据绑定 命令绑定 事件绑定 View和ViewModel的通信 MVVM模式
WPF 数据绑定 命令绑定 事件绑定 View和ViewModel的通信


