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