AssociatedObject.Content 在一定范围后抛出异常
AssociatedObject.Content throws exception after a certain scope
我正在为一些用户控件附加一个行为,当我添加 UI 元素时(请参阅 IsEnable() 方法)它工作正常。在收到通知的某个时间点后,我想更新作为内容添加到用户控件的 Texblock(请参阅 LiveAnalysisIsDone() 方法)。问题是访问 CustomControlContent.Content 会抛出异常 "The calling thread cannot access this object as a different thread owns it"。请帮忙
public class UserControlLiveAnalysisBehaviour : System.Windows.Interactivity.Behavior<UserControl>
{
private TextBlock textBlock = new TextBlock();
private UserControl CustomControlContent;
private bool IsExecuted;
protected override void OnAttached()
{
AssociatedObject.Loaded += UserControlLoadedHandler;
}
private void UserControlLoadedHandler(object sender, RoutedEventArgs e)
{
RegisterUserControlActivatedHandler();
Messenger.Default.Register<Notifications>(this,
(n) =>
{
if (n == Notifications.LiveAnalysisComplete)
{
LiveAnalysisIsDone();
}
});
}
public void LiveAnalysisIsDone()
{
string LiveAnalysisCompleteText = System.Windows.Application.Current.TryFindResource("LiveAnalysisComplete").ToString();
if (CustomControlContent.Content != null) //Exception here The calling thread cannot access this object as a different thread owns it
{
//Remove Children from UserControl
if (CustomControlContent.GetType() != typeof(BioRad.ddPCR.UI.Views.Analysis.Reports.ReportGeneratorUserControl))
{
//var childGrid = WPFUtils.FindChild<Grid>(CustomControlContent, "ContentGrid");
//var c = CustomControlContent.Content as Grid;
//Grid child = CustomControlContent.FindName("ContentGrid") as Grid;
//child.Children.Remove(child.FindName("SpTextPanel") as StackPanel);
////Add new children
//StackPanel sp = new StackPanel();
//sp.HorizontalAlignment = HorizontalAlignment.Center;
//sp.VerticalAlignment = VerticalAlignment.Center;
//sp.Children.Add(new TextBlock { Text = System.Windows.Application.Current.TryFindResource("LiveAnalysisComplete").ToString(), Foreground = new SolidColorBrush(TextBlockStyle()), Effect = null, HorizontalAlignment = HorizontalAlignment.Center, TextAlignment = TextAlignment.Center, FontWeight = FontWeights.SemiBold });
//sp.Effect = null;
//child.Children.Add(sp);
textBlock.Text = System.Windows.Application.Current.TryFindResource("LiveAnalysisComplete").ToString();
}
}
}
private void RegisterUserControlActivatedHandler()
{
CustomControlContent = AssociatedObject;
if (CustomControlContent == null)
{
return;
}
var RunDataInstance = RunDataViewModel.Instance;
RunDataViewModel.RunDataFileSession<string> session = RunDataInstance.GetLiveSessionObject();
if (session != null)
{
if (session.IsLiveAnalysisSession && !IsExecuted)
{
if (CustomControlContent.GetType() == typeof(BioRad.ddPCR.UI.Views.Analysis.Reports.ReportGeneratorUserControl))
{
var child = CustomControlContent.FindName("btnGenerateReport") as Button;
if (child != null)
{
child.IsEnabled = false;
IsExecuted = true;
return;
}
}
textBlock.Text = System.Windows.Application.Current.TryFindResource("LiveAnalysisInProgress").ToString();
IsEnabled();
}
}
}
private void IsEnabled()
{
Grid grid = new Grid();
grid.Name = "ContentGrid";
RowDefinition r1 = new RowDefinition();
r1.Height = new GridLength(30, GridUnitType.Auto);
grid.RowDefinitions.Add(r1);
RowDefinition r2 = new RowDefinition();
r2.Height = new GridLength(30, GridUnitType.Auto);
grid.RowDefinitions.Add(r2);
ContentControl cc = new ContentControl();
StackPanel Sp = new StackPanel();
Sp.Name = "SpTextPanel";
Sp.HorizontalAlignment = HorizontalAlignment.Center;
Sp.VerticalAlignment = VerticalAlignment.Center;
Panel.SetZIndex(Sp, 1000);
Sp.Children.Add(new TextBlock { Text = textBlock.Text, Foreground = new SolidColorBrush(TextBlockStyle()), Effect = null, HorizontalAlignment = HorizontalAlignment.Center, TextAlignment = TextAlignment.Center, FontWeight = FontWeights.SemiBold });
Sp.Background = Brushes.Transparent;
BlurEffect effect = new BlurEffect();
effect.Radius = 7;
(CustomControlContent.Content as UIElement).Effect = effect;
Grid.SetRowSpan(cc, 2);
Sp.Effect = null;
cc.Content = CustomControlContent.Content;
Grid.SetRow(Sp, 0);
grid.Children.Add(cc);
grid.Children.Add(Sp);
CustomControlContent.Content = grid;
IsExecuted = true;
}
public Color TextBlockStyle()
{
if (Brushes.White.Equals(CustomControlContent.Background) || Brushes.WhiteSmoke.Equals(CustomControlContent.Background))
{
return Colors.Gray;
}
else
{
return Colors.White;
}
}
}
好的,正如其他帖子所建议的那样The calling thread cannot access this object because a different thread owns it 我正在使用 Dispatcher,它工作得很好。这是我使用 Dispatcher 更新进度的地方。
public void LiveAnalysisIsDone()
{
string LiveAnalysisCompleteText = System.Windows.Application.Current.TryFindResource("LiveAnalysisComplete").ToString();
if (CustomControlContent != null) {
//Remove Children from UserControl
if (CustomControlContent.GetType() != typeof(BioRad.ddPCR.UI.Views.Analysis.Reports.ReportGeneratorUserControl))
{
this.Dispatcher.BeginInvoke((Action)(() =>
{
var content = CustomControlContent.Content as Grid;
if (content != null)
{
var Panel = content.Children[1] as StackPanel;
(Panel.Children[0] as TextBlock).Text = LiveAnalysisCompleteText;
}
}));
}
}
}
我正在为一些用户控件附加一个行为,当我添加 UI 元素时(请参阅 IsEnable() 方法)它工作正常。在收到通知的某个时间点后,我想更新作为内容添加到用户控件的 Texblock(请参阅 LiveAnalysisIsDone() 方法)。问题是访问 CustomControlContent.Content 会抛出异常 "The calling thread cannot access this object as a different thread owns it"。请帮忙
public class UserControlLiveAnalysisBehaviour : System.Windows.Interactivity.Behavior<UserControl>
{
private TextBlock textBlock = new TextBlock();
private UserControl CustomControlContent;
private bool IsExecuted;
protected override void OnAttached()
{
AssociatedObject.Loaded += UserControlLoadedHandler;
}
private void UserControlLoadedHandler(object sender, RoutedEventArgs e)
{
RegisterUserControlActivatedHandler();
Messenger.Default.Register<Notifications>(this,
(n) =>
{
if (n == Notifications.LiveAnalysisComplete)
{
LiveAnalysisIsDone();
}
});
}
public void LiveAnalysisIsDone()
{
string LiveAnalysisCompleteText = System.Windows.Application.Current.TryFindResource("LiveAnalysisComplete").ToString();
if (CustomControlContent.Content != null) //Exception here The calling thread cannot access this object as a different thread owns it
{
//Remove Children from UserControl
if (CustomControlContent.GetType() != typeof(BioRad.ddPCR.UI.Views.Analysis.Reports.ReportGeneratorUserControl))
{
//var childGrid = WPFUtils.FindChild<Grid>(CustomControlContent, "ContentGrid");
//var c = CustomControlContent.Content as Grid;
//Grid child = CustomControlContent.FindName("ContentGrid") as Grid;
//child.Children.Remove(child.FindName("SpTextPanel") as StackPanel);
////Add new children
//StackPanel sp = new StackPanel();
//sp.HorizontalAlignment = HorizontalAlignment.Center;
//sp.VerticalAlignment = VerticalAlignment.Center;
//sp.Children.Add(new TextBlock { Text = System.Windows.Application.Current.TryFindResource("LiveAnalysisComplete").ToString(), Foreground = new SolidColorBrush(TextBlockStyle()), Effect = null, HorizontalAlignment = HorizontalAlignment.Center, TextAlignment = TextAlignment.Center, FontWeight = FontWeights.SemiBold });
//sp.Effect = null;
//child.Children.Add(sp);
textBlock.Text = System.Windows.Application.Current.TryFindResource("LiveAnalysisComplete").ToString();
}
}
}
private void RegisterUserControlActivatedHandler()
{
CustomControlContent = AssociatedObject;
if (CustomControlContent == null)
{
return;
}
var RunDataInstance = RunDataViewModel.Instance;
RunDataViewModel.RunDataFileSession<string> session = RunDataInstance.GetLiveSessionObject();
if (session != null)
{
if (session.IsLiveAnalysisSession && !IsExecuted)
{
if (CustomControlContent.GetType() == typeof(BioRad.ddPCR.UI.Views.Analysis.Reports.ReportGeneratorUserControl))
{
var child = CustomControlContent.FindName("btnGenerateReport") as Button;
if (child != null)
{
child.IsEnabled = false;
IsExecuted = true;
return;
}
}
textBlock.Text = System.Windows.Application.Current.TryFindResource("LiveAnalysisInProgress").ToString();
IsEnabled();
}
}
}
private void IsEnabled()
{
Grid grid = new Grid();
grid.Name = "ContentGrid";
RowDefinition r1 = new RowDefinition();
r1.Height = new GridLength(30, GridUnitType.Auto);
grid.RowDefinitions.Add(r1);
RowDefinition r2 = new RowDefinition();
r2.Height = new GridLength(30, GridUnitType.Auto);
grid.RowDefinitions.Add(r2);
ContentControl cc = new ContentControl();
StackPanel Sp = new StackPanel();
Sp.Name = "SpTextPanel";
Sp.HorizontalAlignment = HorizontalAlignment.Center;
Sp.VerticalAlignment = VerticalAlignment.Center;
Panel.SetZIndex(Sp, 1000);
Sp.Children.Add(new TextBlock { Text = textBlock.Text, Foreground = new SolidColorBrush(TextBlockStyle()), Effect = null, HorizontalAlignment = HorizontalAlignment.Center, TextAlignment = TextAlignment.Center, FontWeight = FontWeights.SemiBold });
Sp.Background = Brushes.Transparent;
BlurEffect effect = new BlurEffect();
effect.Radius = 7;
(CustomControlContent.Content as UIElement).Effect = effect;
Grid.SetRowSpan(cc, 2);
Sp.Effect = null;
cc.Content = CustomControlContent.Content;
Grid.SetRow(Sp, 0);
grid.Children.Add(cc);
grid.Children.Add(Sp);
CustomControlContent.Content = grid;
IsExecuted = true;
}
public Color TextBlockStyle()
{
if (Brushes.White.Equals(CustomControlContent.Background) || Brushes.WhiteSmoke.Equals(CustomControlContent.Background))
{
return Colors.Gray;
}
else
{
return Colors.White;
}
}
}
好的,正如其他帖子所建议的那样The calling thread cannot access this object because a different thread owns it 我正在使用 Dispatcher,它工作得很好。这是我使用 Dispatcher 更新进度的地方。
public void LiveAnalysisIsDone()
{
string LiveAnalysisCompleteText = System.Windows.Application.Current.TryFindResource("LiveAnalysisComplete").ToString();
if (CustomControlContent != null) {
//Remove Children from UserControl
if (CustomControlContent.GetType() != typeof(BioRad.ddPCR.UI.Views.Analysis.Reports.ReportGeneratorUserControl))
{
this.Dispatcher.BeginInvoke((Action)(() =>
{
var content = CustomControlContent.Content as Grid;
if (content != null)
{
var Panel = content.Children[1] as StackPanel;
(Panel.Children[0] as TextBlock).Text = LiveAnalysisCompleteText;
}
}));
}
}
}