首先,这是使用MVVM的向导控件的简化版本。问题更容易重现,如下所述
经过大幅缩小,我在代码中解决了无限异常,因为WPF ContentControl
。但是,我还没有弄清楚如何处理它,除了try-catch包装我所有可能的实例化代码。以下是重现此内容的示例代码...非常感谢有关如何防止此无限异常发生的任何帮助。
其他详细信息
总而言之,问题是如果内容控件更改其内容,并且正在加载的东西抛出异常,那么它将抛出,然后重试加载,一次又一次地导致抛出。
MainWindow.xaml
<Window x:Class="WpfApplication8.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Name ="Main">
<Grid>
<ContentControl Name="bar" Content="{Binding ElementName=Main, Path=foo}"/>
<Button Click="ButtonBase_OnClick" Margin="20" Width="50"/>
</Grid>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window, INotifyPropertyChanged
{
private UserControl _foo;
public UserControl foo
{
get { return _foo; }
set { _foo = value; OnPropertyChanged("foo"); }
}
public MainWindow()
{
InitializeComponent();
foo = new UserControl1();
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
foo = new UserControl2();
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
UserControl1为空白且均为默认
UserControl2.xaml.cs
public UserControl2()
{
InitializeComponent();
throw new Exception();
}
答案 0 :(得分:0)
不要将ContentControl绑定到MainWindow。而是使用DataTemplates选择MainWindow的内容。一个示例设计的方法是将ContentControl的内容绑定到MainWindow的DataContext。
首先需要一些可观察的测试数据。这些数据的细节并不重要。重点是有两种不同类型的测试数据可供选择 - TestData.cs :
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
namespace fwWpfDataTemplate
{
// Classes to fill TestData
public abstract class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged("Name");
}
}
}
public class Student : Person { }
public class Employee : Person
{
float _salary;
public float Salary
{
get { return _salary; }
set
{
_salary = value;
OnPropertyChanged("Salary");
}
}
}
public class TestData : ObservableCollection<Person>
{
public TestData()
: base(new List<Person>()
{
new Student { Name = "Arnold" },
new Employee { Name = "Don", Salary = 100000.0f }
}) { }
}
}
然后将DataTemplates添加到MainWindow的资源 - MainWindow.xaml :
<Window x:Class="fwWpfDataTemplate.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:me="clr-namespace:fwWpfDataTemplate"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<DataTemplate DataType="{x:Type me:Student}">
<StackPanel>
<TextBlock Text="Student"/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type me:Employee}">
<StackPanel>
<TextBlock Text="Employee"/>
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="Salary"/>
<TextBlock Text="{Binding Salary}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Content="Change Data Context" Click="Button_Click" />
<ContentControl Grid.Row="1" Content="{Binding}"/>
</Grid>
</Window>
注意:DataTemplates的内容可能是UserControl1,UserControl2等,而不是StackPanels。
然后添加一些代码来更改数据上下文 - MainWindow.cs :
using System.Windows;
namespace fwWpfDataTemplate
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
TestData testData = new TestData();
int testIndex = -1;
private void Button_Click(object sender, RoutedEventArgs e)
{
testIndex = (testIndex + 1) % testData.Count;
this.DataContext = testData[testIndex];
}
}
}
享受。