2

I recently experience an argument exception: Must create DependencySource on same Thread as the DependencyObject.

And I know the root cause is trying to instantiate/new object to binding property on different thread rather than the first one, it will cause exception.

However it bring another question that why it WILL NOT throw exception if I instantiate/new string to binding property to update, for example, TextBlock's Text property?

Following is the code that won't throw exception.

==in xaml==
<TextBlock FontSize="20" Text="{Binding FirstName}"/>

==in view model==
private string firstName;
public string FirstName
{
    get { return firstName; }
    set 
    {
        firstName = value;
        RaisePropertyChnaged("FirstName");
    }
}

==in xaml.cs==
public MainWindow()
{
    InitializeComponent();
    this.DataContext = mViewModel = new MainViewModel();
    mViewModel.Color = new SolidColorBrush(Colors.Green);
    mViewModel.FirstName = "John";
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    //intent to udpate Textblock's Text on worker thread
    Task.Run(() => {                
        mViewModel.FirstName = "Andy";
    });
}

Following is the code will throw ArgumentException

==in xaml==
<Rectangle Width="100" Height="100" Fill="{Binding Color}"/>

==in view model==
private SolidColorBrush color;
public SolidColorBrush Color
{
    get { return color; }
    set 
    { 
        color = value;
        RaisePropertyChnaged("Color");
    }
}

==in xaml.cs==
private void Button_Click(object sender, RoutedEventArgs e)
{
    //intent to udpate Rectangle's Fill property on worker thread
    Task.Run(() => {                
        Color = new SolidColorBrush(Colors.Red);
    });
}
howardgod
  • 131
  • 1
  • 6

1 Answers1

2

After change binding property Color's type from SolidBrushColor to Color which is not inherit from DispatcherObject. It will not throw exception anymore.

And there's a similar question which got a good answer to it.

Must create DependencySource on same Thread as DependencyObject

AndrewS's answer clears my head.

Following is modified version

==in xaml==
<Rectangle Width="100" Height="100" Fill="{Binding Color, Converter={StaticResource MyConverter}}"/>

==in view model==
private Color color;
public Color Color
{
    get { return color; }
    set 
    { 
        color = value;
        RaisePropertyChnaged("Color");
    }
}

public class MyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Color c = (Color)value;

        return new SolidColorBrush(c);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

==in xaml.cs==
private void Button_Click(object sender, RoutedEventArgs e)
{
    Task.Run(() => {
        mViewModel.Color = (Colors.Green);
    });
}
Community
  • 1
  • 1
howardgod
  • 131
  • 1
  • 6
  • Yes. And to emphasize: It's not about the DataBinding or RaisePropertyChnaged, the core issue was `new SolidColorBrush()` on a different thread. – H H Jun 16 '15 at 10:37