如何从另一个线程访问和修改绑定到控件属性的依赖项属性?
你好,
我想使用一个简单的例程:如果用户单击一个按钮,则该按钮消失,并且显示进度条.处理完成后,该按钮变为可见.
Hello,
I want to use a simple routine: if user clicks a button, then the button disappears and progress bar shows up. After processing is done, the button becomes visible.
viewModel.StartRendering();
string script = viewModel.LilyScript;
ThreadStart x = delegate
{
Thread.Sleep(1000); // simulate long processing
lily.ProcessScript(script);
Dispatcher.Invoke(new Action(delegate
{
viewModel.LilyRenderOutput = lily.ImageSource;
viewModel.EndRendering();
}), DispatcherPriority.Normal);
};
Thread thr = new Thread(x);
thr.Name = "Renderowanie";
thr.Start();
viewModel具有dep属性,这些属性绑定到控件的属性.
The viewModel has dep properties which are bound to controls'' properties.
class MainWindowVM
{
...
// (obvious code omitted)
public Visibility RenderingProgressBarVisibility...
public static readonly DependencyProperty ...
public Visibility PaintNotesButtonVisibility...
public static readonly DependencyProperty ...
public ImageSource LilyRenderOutput
internal void StartRendering()
{
RenderingProgressBarVisibility = Visibility.Visible;
PaintNotesButtonVisibility = Visibility.Hidden;
}
internal void EndRendering()
{
RenderingProgressBarVisibility = Visibility.Hidden;
PaintNotesButtonVisibility = Visibility.Visible;
}
}
我有一个异常调用线程无法访问该对象,因为其他线程拥有它.在线
I got an exception The calling thread cannot access this object because a different thread owns it. on line
viewModel.LilyRenderOutput = lily.ImageSource;
在xaml中:
In xaml:
<Image Source="{Binding LilyRenderOutput}" Stretch="None" />
有趣的事实:代码
Interesting fact: the code
Dispatcher.Invoke(new Action(delegate
{
this.Title="abc";
}), DispatcherPriority.Normal);
确实有效.我使用错误的调度程序还是什么?我尝试过viewModel.Dispather没有成功.
感谢任何帮助.
does work. Do I use a wrong dispatcher or what? I tried viewModel.Dispather with no success.
Any help appreciated.
根本原因在于Windows Presentation Framework的体系结构.
使用WPF时,请注意,如果在一个线程中创建UI对象,则无法从另一个线程访问它.您的UI对象(通常)应该创建UI线程,然后需要UI线程以后才能访问它们.其他线程将无法访问在UI线程上创建的对象.
如果需要从另一个线程访问UI对象,则需要UI线程Dispatcher,然后可以使用它来调用UI线程上的调用.
希望它可以澄清您的查询.
Root cause is due to the architecture of Windows Presentation Framework.
When working with WPF be aware that if you create a UI object in one thread you can''t access it from another thread. Your UI objects should (typically) be created the UI thread, and then you need the UI thread to access them later. No other thread will be able to access objects created on the UI thread.
If you need to access a UI object from another thread you need the UI thread Dispatcher, and then you can use this to invoke calls on the UI thread.
Hope, it clarifies your query.