0

I am trying to display a menu element in my application as soon as a specific bluetooth message arrives. The messages are collected and interpreted through a timer method and if the correct message arrives, the element should be rendered visible. I keep getting an exception telling me that the object is owned by another thread and cannot be accessed.

// Shows a TangibleMenu element
private void Show(TangibleMenu TangibleMenuElement)
{
    if (TangibleMenuElement.Shape.CheckAccess())
    {
        Debug.WriteLine("normal show");
        TangibleMenuElement.Shape.Opacity = 1;
        TangibleMenuElement.Shape.Visibility = System.Windows.Visibility.Visible;
        this.ParentContainer.Activate(TangibleMenuElement.Shape);
    }
    else
    {
        Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
        {
            Debug.WriteLine("dispatcher show");
            TangibleMenuElement.Shape.Opacity = 1; // EXCEPTION HERE
            TangibleMenuElement.Shape.Visibility = System.Windows.Visibility.Visible;
            this.ParentContainer.Activate(TangibleMenuElement.Shape);
        }));
    }
}

I thought that this exact issue could be solved by using the Dispatcher but in this case, it doesn't seem to work. TangibleMenuElement.Shape is a ScatterViewItem from the Microsoft Surface SDK. Does anyone have any suggestions?

4

3 回答 3

0

我的问题的解决方案:我访问了错误的 Dispatcher ...

我没有注意Dispatcher.CurrentDispatcher和 Application.Current.Dispatcher 的区别。第一个返回当前线程的调度程序,第二个返回在我的情况下的 UI 线程(应用程序的第一个线程)。

所以我的 Timer 线程收到了消息,称为Show(),要求一个 Dispatcher 并得到一个......但它是 Timer 线程的 Dispatcher 而不是 UI 线程。当我将代码更改为Application.Current.Dispatcher按预期工作时。

更详细的解释可以在这里找到。

于 2013-10-23T23:52:48.593 回答
0

TangibleMenuElement需要在 UI 线程上创建,而不仅仅是在 UI 线程上添加到容器中。这意味着您需要FrameworkElement完全在 UI 线程上构建。

于 2013-10-23T22:45:50.393 回答
0

尝试这个

// Shows a TangibleMenu element
private void Show(TangibleMenu TangibleMenuElement)
{
    App.Current.Dispatcher.Invoke(new Action(() =>
    {
        if (TangibleMenuElement.Shape.CheckAccess())
        {
            Debug.WriteLine("normal show");
            TangibleMenuElement.Shape.Opacity = 1;
            TangibleMenuElement.Shape.Visibility = System.Windows.Visibility.Visible;
            this.ParentContainer.Activate(TangibleMenuElement.Shape);
        }
        else
        {
            Debug.WriteLine("dispatcher show");
            TangibleMenuElement.Shape.Opacity = 1; // EXCEPTION HERE
            TangibleMenuElement.Shape.Visibility = System.Windows.Visibility.Visible;
            this.ParentContainer.Activate(TangibleMenuElement.Shape);
        }
    }));
}
于 2013-10-23T22:59:00.723 回答