我有一个错误"必须在与DependencyObject相同的线程上创建DependencySource"在我的项目中。
我的评论用于加载文件并创建列表。此列表绑定到ListBox。 AL工作得很好。但是我创建了一个要加载的任务(加载可以很长)。现在我有这个错误。我不明白为什么会这样。
有我的代码:
MainView.xaml:
<ListBox ItemsSource="{Binding Results}"
SelectedItem="{Binding SelectedItem}">
<ListBox.InputBindings>
<KeyBinding Command="{Binding RemoveCommand}"
Key="Delete"/>
</ListBox.InputBindings>
</ListBox>
<Button Grid.Row="1" Grid.Column="0"
Style="{StaticResource StyleButton}"
Command="{Binding LoadCommand}"
Content="Open result"/>
MainViewModel:
#region Fields/Properties
public ImageWithPoints SelectedItem
{
get
{
return _selectedItem;
}
set
{
_selectedItem = value;
SelectedPointIndex = 1;
OnPropertyChanged();
OnPropertyChanged("Picture");
UpdatePoints();
}
}
public List<ImageWithPoints> Results
{
get
{
return _results;
}
set
{
_results = value;
if (value == null)
{
SelectedPointIndex = 0;
}
OnPropertyChanged();
}
}
public BitmapSource Picture
{
get
{
return SelectedItem?.Picture;
}
}
#endregion
#region Load
private ICommand _loadCommand;
public ICommand LoadCommand
{
get
{
if (_loadCommand == null)
_loadCommand = new RelayCommand(OnLoad, CanLoad);
return _loadCommand;
}
}
public void OnLoad()
{
StartRunning(this, null);
Task loadTask = new Task(new Action(() =>
{
Load();
Application.Current.Dispatcher.Invoke(new Action(() =>
{
StopRunning(this, null);
}));
}));
loadTask.Start();
}
public bool CanLoad()
{
return !IsRunning;
}
#endregion
#region Events
public event EventHandler OnStartRunning;
public event EventHandler OnStopRunning;
private void StartRunning(object sender, EventArgs e)
{
OnStartRunning(sender, e);
}
private void StopRunning(object sender, EventArgs e)
{
OnStopRunning(sender, e);
}
#enregion
#region Methods
public void Load()
{
// Open File
// Set to list
List<ImageWithPoints> listRes;
Results = listRes;
SelectedItem = Results[0];
}
#endregion
当我删除该行SelectedItem = Results[0];
时,我没有错误(但是应用程序没有工作)。
答案 0 :(得分:1)
任务完成后,在UI线程上重新设置SelectedItem属性:
public void OnLoad()
{
StartRunning(this, null);
Task.Factory.StartNew(new Action(() =>
{
Load();
})).ContinueWith(task =>
{
SelectedItem = Results[0];
StopRunning(this, null);
}, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
}
您只能访问最初创建它的线程上的UI元素,因此如果您的UpdatePoints()
方法访问必须在UI线程上调用此方法的任何控件。