Must create DependencySource on same Thread as the DependencyObject

WPF 错误:Must create DependencySource on same Thread as the DependencyObject

先看数据模型类吧

    public class MessageInfo
    {
        public string Message { get; set; }
        public FontWeight FontWeight { get; set; }
        public SolidColorBrush Foreground { get; set; }
    }
    class M_LoadBKCData : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void RaisePropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        private ObservableCollection<MessageInfo> _Message = new ObservableCollection<MessageInfo>();
        public ObservableCollection<MessageInfo> Message
        {
            get { return _Message; }
            set
            {
                if (_Message != value)
                {
                    _Message = value;
                    this.RaisePropertyChanged("Message");
                }
            }
        }
    }

然后看模型绑定到的WPF XAML 代码

  <Grid x:Name="Grid1">
      <ItemsControl FontSize="14" Foreground="Gray" Visibility="Visible" Grid.Row="1" ItemsSource="{Binding Message}">
           <ItemsControl.ItemTemplate>
              <DataTemplate>
                  <Label x:Name="PART_Label" FontWeight="{Binding FontWeight}" Foreground="{Binding Foreground}" 
                      Content="{Binding Message}" Margin="0,2"/>
                  <DataTemplate.Triggers>
                      <DataTrigger Binding="{Binding FontWeight}" Value="{x:Static FontWeights.Normal}">
                          <Setter Property="Padding" Value="10,0,0,0" TargetName="PART_Label"/>
                      </DataTrigger>
                  </DataTemplate.Triggers>
              </DataTemplate>
          </ItemsControl.ItemTemplate>                       
      </ItemsControl>
  </Grid>

后台代码大概如下

    M_LoadBKCData Model = new M_LoadBKCData();
    Grid1.DataContext = Model;
    Model.Message.Add(new MessageInfo() { 
      Message = "第一条消息", FontWeight = FontWeights.Bold, Foreground = new SolidColorBrush(Colors.Red) 
    });  //这条数据会再界面显示

然后开启一个线程,如下代码将会报错

    Task.Factory.StartNew(() =>
    {
        Thread.Sleep(5000);
        SolidColorBrush foreground =new SolidColorBrush(Colors.Black);
        MessageInfo msgInfo = new MessageInfo()
        {
            Message = "下一条消息",
            FontWeight = FontWeights.Normal,
            Foreground = foreground
        };

        Grid1.Dispatcher.Invoke(() => {
            Model.Message.Add(msgInfo);
        });
    });

报错如下图

报错原因:SolidColorBrush属于WPF对象,当前情况是在另外的线程创建的,导致出现问题,需要修改为如下

 Task.Factory.StartNew(() =>
 {
      Thread.Sleep(5000); 
      Grid1.Dispatcher.Invoke(() => {
          SolidColorBrush foreground = new SolidColorBrush(Colors.Black);
          MessageInfo msgInfo = new MessageInfo()
          {
              Message = "下一条消息",
              FontWeight = FontWeights.Normal,
              Foreground = foreground
          };
          Model.Message.Add(msgInfo);
      });
});

如果时用了MVVM模式, Model层有INotify类型的 属性, 若果是WPF的类相关的,需要特别注意下,
不能在其他线程中进行实例化,看下SolidColorBrush的定义,继承DependencyObject

  public sealed class SolidColorBrush : Brush                            {    }
  public abstract class Brush : Animatable, IFormattable, IResource      {    }
  public abstract class Animatable : Freezable, IAnimatable, IResource   {    }
  public abstract class Freezable : DependencyObject, ISealable          {    }
posted @   老板娘的神秘商店  阅读(233)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示
主题色彩
不要让你喜欢的人在约会,而你却在加班