Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 运行时更改椭圆颜色_C#_Wpf_Multithreading - Fatal编程技术网

C# 运行时更改椭圆颜色

C# 运行时更改椭圆颜色,c#,wpf,multithreading,C#,Wpf,Multithreading,我没有经常使用wpf,并且认为在运行时更改椭圆的颜色是一个简单的过程。我有一个FileWatcher,在创建的事件中,我想将椭圆的颜色更改为一种颜色,然后再次更改,以创建闪烁效果。(创建的是椭圆,br4是用xaml定义的纯色笔刷) 一旦在引发事件的路径中创建了文件,我就会收到以下错误:操作异常无效 调用线程无法访问此对象,因为其他线程拥有它。 我用freeze()方法寻找了一个解决方案,但没有成功 created.Dispatcher.Invoke(System.Windows.Thr

我没有经常使用wpf,并且认为在运行时更改椭圆的颜色是一个简单的过程。我有一个FileWatcher,在创建的事件中,我想将椭圆的颜色更改为一种颜色,然后再次更改,以创建闪烁效果。(创建的是椭圆,br4是用xaml定义的纯色笔刷)

一旦在引发事件的路径中创建了文件,我就会收到以下错误:操作异常无效 调用线程无法访问此对象,因为其他线程拥有它。 我用freeze()方法寻找了一个解决方案,但没有成功

     created.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(
            delegate()
            {
                Application.Current.Resources["br4"] = new SolidColorBrush(Colors.Green);
                created.Fill = (SolidColorBrush)Application.Current.Resources["br4"];
            }
        ));

感谢您的评论

您只能从创建UI元素的同一线程访问它们

您应该使用Dispatcher.Invoke或Dispatcher.BeginInvoke在UI线程上调用一个委托…然后您可以在其中访问“创建的”元素的“填充”属性

有关问题的说明,请参阅此链接:

与其尝试在UI中设置不断变化的颜色,您可以做的是在ViewModel上公开一个保存状态的属性

当FileWatcher通知您新创建的文件时(通过调用watcherCreated方法),您只需在ViewModel中设置该状态

在UI中…使用带有转换器的绑定绑定到ViewModel中的state属性。转换器将根据状态确定要使用的电刷,例如,如果状态为1,则返回绿色电刷,如果状态为0,则返回红色电刷

要将状态重置回“关闭”位置,您可以使用一个计时器,在1秒后,将状态值设置回“关闭”

通过这样做……您可以将状态与UI分离


如果将来你想用更复杂的方式在UI中显示状态…例如。让动画(使用故事板/视觉状态管理器)逐渐从绿色变回红色…然后您可以根据ViewModel中的状态再次触发该动画。

更简单的解决方案是在UI线程本身上设置created.Fill。您不需要Dispatcher.Invoke或Dispatcher.BeginInvoke

在WPF中,当应用程序在单独的线程中运行时,所有UI控件都加载到不同的线程中

因此,可以这样认为,您遇到此错误是因为您的应用程序(主线程)正在尝试访问UIThread中的Elipse。这是不允许的,因为线程不能直接访问彼此的对象

所以WPF引入了dispatcher对象。使用以下命令


我看到过一些这样的例子,我认为会有一个简单的解决方案。我将再次研究这个问题,感谢您对类似(完全相同?)问题的回答(wpf部分)。
     created.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(
            delegate()
            {
                Application.Current.Resources["br4"] = new SolidColorBrush(Colors.Green);
                created.Fill = (SolidColorBrush)Application.Current.Resources["br4"];
            }
        ));
if (this.Dispatcher.Thread != System.Threading.Thread.CurrentThread)
{
    this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,
        new Action(
            delegate()
            {
                Application.Current.Resources["br4"] = new SolidColorBrush(Colors.Green);
                created.Fill = (SolidColorBrush)Application.Current.Resources["br4"];
            }
            ));
}