//树视图数据源
private ObservableCollection<Node> nodes = new ObservableCollection<Node> () ;
public ObservableCollection<Node> Nodes
{
get
{
return nodes;
}
set { nodes = value; RaisePropertyChanged(() => Nodes); }
}
public void FillNode()
{
try
{
nodes_c.Add(integration_.SocialChat(casePath_, Applist_["测试1"], Userlist_));
nodes_c.Add(integration_.SocialChat(casePath_, Applist_["测试2"], Userlist_));
nodes_c.Add(integration_.SocialChat(casePath_, Applist_["测试3"], Userlist_));
}
catch (Exception ex)
{
//log
}
}
public CaseViewModel()
{
//这里是用MvvmLight的Messenger触发的Load方法
Messenger.Default.Register<DataHelper>(this, "DB", Load);
}
public async void Load(DataHelper x)
{
await Task.Run(FillNode);
//这里是网上找的方法,但是不起作用。
//效果等于直接写Nodes = new ObservableCollection<Node>(nodes_c);
ThreadPool.QueueUserWorkItem(delegate
{
System.Threading.SynchronizationContext.SetSynchronizationContext(new
System.Windows.Threading.DispatcherSynchronizationContext(System.Windows.Application.Current.Dispatcher));
System.Threading.SynchronizationContext.Current.Post(pl =>
{
//把FillNode里临时的nodes_c 赋值给XAML绑定的Nodes属性
Nodes = new ObservableCollection<Node>(nodes_c);
LogHelper.log_.Warn(Nodes.Count);
}, null);
});
}
用
Application.Current.Dispatcher.Invoke(action);
代替ThreadPool.QueueUserWorkItem的一堆
这个action就是楼上invoke里面的action
用这个直接就invoke到ui线程执行了
我试过了还是不行,依然报错
public async void Load(DataHelper x)
{
await Task.Run(FillNode);
Application.Current.Dispatcher.Invoke(new Action(() =>
{
//把FillNode里临时的nodes_c 赋值给XAML绑定的Nodes属性
Nodes = new ObservableCollection<Node>(nodes_c);
LogHelper.log_.Warn(Nodes.Count);
}));
Messenger.Default.Unregister<DataHelper>(this, "DB");
}
报错【System.Windows.Markup.XamlParseException:“必须在与 DependencyObject 相同的线程上创建 DependencySource。”】
@神奇玩偶obbb: 你的nodes_c是在哪里初始华的,
@神奇玩偶obbb:
试试
void Load()
{
Task.Factory.StartNew(() =>
{
//复杂操作
nodes_c=new xxx();
nodes_c.add(xx);
nodes_c.add(xx);
nodes_c.add(xx);
Action action = new Action(() =>
{
Node=new xx(){nodes_c};
}
});
Application.Current.Dispatcher.Invoke(action);
});
}
@猝不及防: 刚刚看到。好的 我去 试一下
@猝不及防:
试过了还是不行。
public void FillNode()
{
Task.Factory.StartNew(() =>
{
List<Node> nodes_c = new List<Node>();
try
{
nodes_c.Add(integration_.SocialChat(casePath_, Applist_["t1"], Userlist_));
nodes_c.Add(integration_.Video(casePath_, Applist_["t2"], Userlist_));
nodes_c.Add(integration_.SocialMedia(casePath_, Applist_["t3"], Userlist_));
}
catch (Exception ex)
{
}
Debug.WriteLine("节点加载完成");
Action action = new Action(() => {
Nodes = new ObservableCollection<Node>(nodes_c);
LogHelper.log_.Warn(Nodes.Count);
});
Application.Current.Dispatcher.Invoke(action);
});
}
public async void Load(DataHelper x)
{
FillNode();
Messenger.Default.Unregister<DataHelper>(this, "DB");
}
因为你在异步方法里面用了ui的代码,所以报这个错
对,我就是要异步去加载数据然后展示出来。因为不用异步的加载话,这个流程需要卡死 几十秒。
Invoke(new Action(()=>{
Nodes = new ObservableCollection<Node>(nodes_c);
LogHelper.log_.Warn(Nodes.Count);
}));
我试过了还是不行,依然报错
public async void Load(DataHelper x)
{
await Task.Run(FillNode);
Application.Current.Dispatcher.Invoke(new Action(() =>
{
//把FillNode里临时的nodes_c 赋值给XAML绑定的Nodes属性
Nodes = new ObservableCollection<Node>(nodes_c);
LogHelper.log_.Warn(Nodes.Count);
}));
Messenger.Default.Unregister<DataHelper>(this, "DB");
}
报错【System.Windows.Markup.XamlParseException:“必须在与 DependencyObject 相同的线程上创建 DependencySource。”】
@神奇玩偶obbb: 你的nodes_c是在哪里初始化的?
@神奇玩偶obbb: 没搞过WPF,反正你这个是多线程的问题。不难。你再研究研究。
因为你修改控件的线程不是创建控件的线程。其实你为什么要这样做。你把model绑定到ui,只需修改model,UI自然就变了。你这样做回退到了winform时代了。
我操作的就是TreeView绑定的 集合。但是我Task执行完方法后去操作这个集合的时候。就报那个错
@神奇玩偶obbb: 如果有空的话写个简单的可运行的demo发来,我调试下试试
谢谢各位大佬给的解决方案。实际是我疏忽了代码。我再XAML代码的模板中绑定了Model中的Brush 类型的Color属性,在异步代码中创建Model实例,并且初始化了Color属性。导致跨线程错误。使用转换器解决。
public class ColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (UtilityToolSuite.Tool.SafetyTransformInt32(value) == 0)
{
return new SolidColorBrush(Color.FromRgb(0, 0, 0));
}
else
{
return new SolidColorBrush(Color.FromRgb(255, 0, 0));
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
<TextBlock VerticalAlignment="Center">
<Run Foreground="{Binding Del,Converter={StaticResource ColorConverter}}" Text="{Binding Del}" />
</TextBlock>