C# 将其发送到UI线程。因此,请确保后台工作完成后,您设置了需要在UI线程上更新的属性。

C# 将其发送到UI线程。因此,请确保后台工作完成后,您设置了需要在UI线程上更新的属性。,c#,wpf,xaml,binding,C#,Wpf,Xaml,Binding,我认为您可能弄乱了列表框的绑定,即(为了简单起见缩短): 这意味着-“在树上第一个AttributesListBox类型的对象中查找名为Source的属性”。当然,您仍然需要将源属性绑定到控制器的正确对象,但我想您已经这样做了 处理属性更改事件的方法是,必须从UI(Dispatcher)线程引发该事件,如果从后台线程引发该事件,wpf将不会自动将其封送到UI线程。因此,请确保在后台工作完成后,您设置了需要在UI线程上更新的属性。问问题的好处是迫使您真正思考问题的原因,因此稍作休息两天后,您可能最

我认为您可能弄乱了列表框的绑定,即(为了简单起见缩短):

这意味着-“在树上第一个AttributesListBox类型的对象中查找名为
Source
的属性”。当然,您仍然需要将
属性绑定到控制器的正确对象,但我想您已经这样做了


处理属性更改事件的方法是,必须从UI(Dispatcher)线程引发该事件,如果从后台线程引发该事件,wpf将不会自动将其封送到UI线程。因此,请确保在后台工作完成后,您设置了需要在UI线程上更新的属性。

问问题的好处是迫使您真正思考问题的原因,因此稍作休息两天后,您可能最终会找到完全简单的解决方案

问题是ParameterizedThreadStart请求一个void方法(object arg),因此只要传递一个对象,编译器就不会进行类型检查。因为我编辑了方法,所以传递了错误的对象。使用“as”操作符的安全类型转换似乎是一种痛苦,它似乎吞下了一个CastingException,因此没有通知您这个小错误

因此,简单的解决方案是:

private static void Host(object viewControler)
{
    var controler = viewControler as IViewController;
    _instance._main = new MainWindow(controler) { DataContext = controler };
    var gui = new App();
    if (_instance._main == null) throw new ArgumentNullException("viewControler");
    gui.Run(controler);
}
我没想到我的后台工作人员会100%地“开箱即用”,但似乎是这样。我的代码是否是“最佳实践”是另一个独立的问题

让我朝这个方向思考的关键是:

在visaul studio中使用数据绑定时,也可以查看这篇小文章:

问问题的好处在于迫使你真正思考问题的原因,因此休息一下,两天后,你可能最终找到完全简单的解决方案

问题是ParameterizedThreadStart请求一个void方法(object arg),因此只要传递一个对象,编译器就不会进行类型检查。因为我编辑了方法,所以传递了错误的对象。使用“as”操作符的安全类型转换似乎是一种痛苦,它似乎吞下了一个CastingException,因此没有通知您这个小错误

因此,简单的解决方案是:

private static void Host(object viewControler)
{
    var controler = viewControler as IViewController;
    _instance._main = new MainWindow(controler) { DataContext = controler };
    var gui = new App();
    if (_instance._main == null) throw new ArgumentNullException("viewControler");
    gui.Run(controler);
}
我没想到我的后台工作人员会100%地“开箱即用”,但似乎是这样。我的代码是否是“最佳实践”是另一个独立的问题

让我朝这个方向思考的关键是:

在visaul studio中使用数据绑定时,也可以查看这篇小文章:

感谢您的回复。代码似乎只与{Binding Source}一起工作,但这可能是巧合,我可以看出您的绑定表达式是如何更安全地工作的。PropertyChanged事件似乎以某种方式(可能是巧合)进入了UI线程。我不使用Dispatcher或DoWorkComplete事件来确保使用UI线程更新属性。这是一个安全的赌注还是值得好好看看?不过,您确实澄清了我的第二个问题。我很惊讶{Binding Source}可以工作,运行时列表框的DataContext是什么(您可以使用codeplex上的“snoop”工具进行检查)?关于InotifyProperty的更改,我错了,今天我学到了一些新的东西=)检查此项谢谢您的回复。代码似乎只与{Binding Source}一起工作,但这可能是巧合,我可以看出您的绑定表达式是如何更安全地工作的。PropertyChanged事件似乎以某种方式(可能是巧合)进入了UI线程。我不使用Dispatcher或DoWorkComplete事件来确保使用UI线程更新属性。这是一个安全的赌注还是值得好好看看?不过,您确实澄清了我的第二个问题。我很惊讶{Binding Source}可以工作,运行时列表框的DataContext是什么(您可以使用codeplex上的“snoop”工具进行检查)?关于InotifyProperty的更改,我错了,今天我学到了一些新的东西=)检查这个我很高兴你发现了问题!我很高兴你发现了这个问题!
    private static void Host(object viewControler)
    {
        var controler = viewControler as IViewController;
        _instance._main = new MainWindow(controler) { DataContext = controler };
        var gui = new App();
        if (_instance._main == null) throw new ArgumentNullException("viewControler");
        gui.Run(_instance._main);
    }
    public AttributesListBox()
    {
        InitializeComponent();
    }

    /// <summary>
    /// The dependency property that gets or sets the source of the ListBox to render.
    /// </summary>
    public static DependencyProperty sourceProperty = DependencyProperty.Register(
        "Source", typeof(IEnumerable), typeof(AttributesListBox),_sourceMetadata);
    /// <summary>
    /// Gets or sets the nsource of the image to render.
    /// </summary>
    public IEnumerable Source
    {
        get { return (IEnumerable)GetValue(sourceProperty); }
        set { SetValue(sourceProperty, value); }
    }

    private static void SourceChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var box = (AttributesListBox) d;
        box.List.ItemsSource = e.NewValue as IEnumerable;
    }
}
<ListBox Name="List" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" ItemsSource="{Binding Source}" BorderBrush="{x:Null}" />
<ListBox ItemsSource="{Binding Source}" />
<ListBox ItemsSource="{Binding Source, RelativeSource={RelativeSource AncestorType={x:Type AttributesListBox}}}" />
private static void Host(object viewControler)
{
    var controler = viewControler as IViewController;
    _instance._main = new MainWindow(controler) { DataContext = controler };
    var gui = new App();
    if (_instance._main == null) throw new ArgumentNullException("viewControler");
    gui.Run(controler);
}