码迷,mamicode.com
首页 > 其他好文 > 详细

Must create DependencySource on same Thread as the DependencyObject

时间:2021-06-02 10:51:43      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:cdata   red   his   mes   name   att   items   对象   abstract   

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

Must create DependencySource on same Thread as the DependencyObject

标签:cdata   red   his   mes   name   att   items   对象   abstract   

原文地址:https://www.cnblogs.com/wandia/p/14811560.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!