Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm using x:Bind (compiled binding) in my UWP app to bind a TextBlock to an integer property in the ViewModel which is converted to a string by a value converter. I am using a method in the ViewModel on the worker thread to set the properties and call the PropertyChanged event. However, I am getting an exception (specifically, it's in the XamlBindingSetters class in the MainPage.g.cs file) saying, "The application called an interface that was marshalled for a different thread." According to this post, this should work just fine in WPF; has this ease of functionality been removed in WinRT/UWP or am I doing something wrong?

Here's exactly what I'm doing.

My property is defined like this:

private int myProperty;

    public int MyProperty
    {
        get { return myProperty; }
        set
        {
            Set(ref myProperty, value);
        }
    }

The Set method is part of the Template 10 library and is defined:

public bool Set<T>(ref T storage, T value, [CallerMemberName]string propertyName = null) 
     { 
         if (object.Equals(storage, value)) 
             return false; 
         storage = value; 
         RaisePropertyChanged(propertyName); 
         return true; 
     } 

Nothing wrong there from what I can see; it just makes sure the new value is different than the old value and then calls RaisePropertyChanged(propertyName) which makes sure the app is actually running (not in design mode) and then raises the PropertyChanged event.

I set my property from a worker thread:

MyProperty = newValue;

and when it gets to the XamlBindingSetters class:

internal class XamlBindingSetters
    {
        public static void Set_Windows_UI_Xaml_Controls_TextBlock_Text(global::Windows.UI.Xaml.Controls.TextBlock obj, global::System.String value, string targetNullValue)
        {
            if (value == null && targetNullValue != null)
            {
                value = targetNullValue;
            }
            obj.Text = value ?? global::System.String.Empty;
        }
    };

it breaks on that last line (obj.Text = ...) and tells me that the application called an interface that was marshalled for a different thread. What am I doing wrong?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
350 views
Welcome To Ask or Share your Answers For Others

1 Answer

You need to execute all graphical objects in the UI Thread.

Typical usage:

obj.Invoke((MethodInvoker) SomeMethod);

See How to Use ISynchronizeInvoke interface?

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...