关于WPF MVVM下,在线程里修改UI绑定值的安全性

ilikeff8 ilikeff8 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区

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}"

...全文

相关推荐

评论 15
收藏 已收藏
分享
返回顶部
ilikeff8
C# 111,129 成员 642,538 内容