用户控制焦点上的 Catel 冻结
Catel freezing on usercontrol focus
我得到了一个带有嵌套用户控件的简单应用程序。
MainWindow.xaml:
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBox Grid.Row="0">Test TextBox</TextBox>
<userControls:SuggestUserControl Grid.Row="1" Grid.Column="0"
DataContext="{Binding CitizenshipViewModel}" />
</Grid>
违反命名约定是随后重新使用此用户控件的原因。在那种情况下,我在 App.xaml.cs:
中注册自定义视图模型
var viewLocator = ServiceLocator.Default.ResolveType<IViewModelLocator>();
viewLocator.Register(typeof(SuggestUserControl), typeof(CitizenshipSuggestViewModel));
CitizenshipSuggestViewModel 是一个简单的 class,具有空构造函数、一些附加逻辑(我在测试响应中评论过)并派生自基础 class SuggestModule:
public class SuggestModule<TEntity> : ViewModelBase
where TEntity : class, ISuggestable, new()
{
#region Private fields
private readonly IDataBaseService _dataBaseService;
#endregion
#region Default constructor
public SuggestModule(IDataBaseService dataBaseService)
{
Argument.IsNotNull(() => dataBaseService);
_dataBaseService = dataBaseService;
//Loading data from context
var collection = _dataBaseService.LoadObservableCollectionOf<TEntity>();
ItemsCollection = new ObservableCollection<TEntity>(collection);
ItemsCollection.Sort();
}
#endregion
...Some logic here...
}
MainWindowViewModel:
public class MainWindowViewModel : ViewModelBase
{
public MainWindowViewModel(Person person)
{
Argument.IsNotNull(()=>person);
Person = person;
}
[Model]
public Person Person
{
get => GetValue<Person>(PersonProperty);
set => SetValue(PersonProperty, value);
}
public static readonly PropertyData PersonProperty =
RegisterProperty<MainWindowViewModel, Person>(model => model.Person);
[ViewModelToModel("Person")]
public Citizenship Citizenship
{
get => GetValue<Citizenship>(CitizenshipProperty);
set => SetValue(CitizenshipProperty, value);
}
public static readonly PropertyData CitizenshipProperty =
RegisterProperty<MainWindowViewModel, Citizenship>(model => model.Citizenship);
public Citizenship Citizenship
{
get => GetValue<Citizenship>(CitizenshipProperty);
set => SetValue(CitizenshipProperty, value);
}
public static readonly PropertyData CitizenshipProperty =
RegisterProperty<MainWindowViewModel, Citizenship>(model => model.Citizenship);
public IViewModel CitizenshipViewModel
{
get => GetValue<IViewModel>(CitizenshipViewModelProperty);
set => SetValue(CitizenshipViewModelProperty, value);
}
public static readonly PropertyData CitizenshipViewModelProperty =
RegisterProperty<MainWindowViewModel, IViewModel>(model => model.CitizenshipViewModel);
protected override async Task InitializeAsync()
{
await base.InitializeAsync();
CitizenshipViewModel = this.GetTypeFactory().CreateInstance<CitizenshipSuggestViewModel>();
}
}
}
因此,当应用程序完全加载时,特别是 SuggestModule 上的 ItemsCollection 已经填充了来自上下文的数据,在 Log 中得到了以下信息:
12:19:34:844 => [DEBUG] [Catel.MVVM.Views.ViewToViewModelMappingHelper] [1] Initializing view model container to manage ViewToViewModel mappings
12:19:34:864 => [DEBUG] [Catel.MVVM.Views.ViewToViewModelMappingHelper] [1] Initializing view model 'CitizenshipSuggestViewModel'
12:19:34:874 => [DEBUG] [Catel.MVVM.Views.ViewToViewModelMappingHelper] [1] Initialized view model 'CitizenshipSuggestViewModel'
12:19:34:895 => [DEBUG] [Catel.MVVM.Views.ViewToViewModelMappingHelper] [1] Initialized view model container to manage ViewToViewModel mappings
但是现在,如果我关注第二个文本框,它是嵌套用户控件的一部分,我有大约 5...6 秒的冻结时间。本次登录信息:
12:23:21:212 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:21:387 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:21:809 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:21:901 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:22:016 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:22:063 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:22:221 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:22:235 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:22:585 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:22:654 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:22:703 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:23:019 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:23:319 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:23:431 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:24:105 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:24:566 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:24:644 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:25:803 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:26:115 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
如何避免这种行为?
提前致谢!
- 我们建议使用 InitializeAsync 而不是数据检索的构造函数
- 您是否将 Catel 5.2 与 VS 2017 结合使用?当您 运行 没有附加调试器时,问题是否仍然出现?
使用 InitializeAsync 代替构造函数进行数据检索
使用 Orc.EntityFramework6 而不是过时的 Catel.Extensions.EntityFramework6
完全解决了我的问题。
我得到了一个带有嵌套用户控件的简单应用程序。
MainWindow.xaml:
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBox Grid.Row="0">Test TextBox</TextBox>
<userControls:SuggestUserControl Grid.Row="1" Grid.Column="0"
DataContext="{Binding CitizenshipViewModel}" />
</Grid>
违反命名约定是随后重新使用此用户控件的原因。在那种情况下,我在 App.xaml.cs:
中注册自定义视图模型var viewLocator = ServiceLocator.Default.ResolveType<IViewModelLocator>();
viewLocator.Register(typeof(SuggestUserControl), typeof(CitizenshipSuggestViewModel));
CitizenshipSuggestViewModel 是一个简单的 class,具有空构造函数、一些附加逻辑(我在测试响应中评论过)并派生自基础 class SuggestModule:
public class SuggestModule<TEntity> : ViewModelBase
where TEntity : class, ISuggestable, new()
{
#region Private fields
private readonly IDataBaseService _dataBaseService;
#endregion
#region Default constructor
public SuggestModule(IDataBaseService dataBaseService)
{
Argument.IsNotNull(() => dataBaseService);
_dataBaseService = dataBaseService;
//Loading data from context
var collection = _dataBaseService.LoadObservableCollectionOf<TEntity>();
ItemsCollection = new ObservableCollection<TEntity>(collection);
ItemsCollection.Sort();
}
#endregion
...Some logic here...
}
MainWindowViewModel:
public class MainWindowViewModel : ViewModelBase
{
public MainWindowViewModel(Person person)
{
Argument.IsNotNull(()=>person);
Person = person;
}
[Model]
public Person Person
{
get => GetValue<Person>(PersonProperty);
set => SetValue(PersonProperty, value);
}
public static readonly PropertyData PersonProperty =
RegisterProperty<MainWindowViewModel, Person>(model => model.Person);
[ViewModelToModel("Person")]
public Citizenship Citizenship
{
get => GetValue<Citizenship>(CitizenshipProperty);
set => SetValue(CitizenshipProperty, value);
}
public static readonly PropertyData CitizenshipProperty =
RegisterProperty<MainWindowViewModel, Citizenship>(model => model.Citizenship);
public Citizenship Citizenship
{
get => GetValue<Citizenship>(CitizenshipProperty);
set => SetValue(CitizenshipProperty, value);
}
public static readonly PropertyData CitizenshipProperty =
RegisterProperty<MainWindowViewModel, Citizenship>(model => model.Citizenship);
public IViewModel CitizenshipViewModel
{
get => GetValue<IViewModel>(CitizenshipViewModelProperty);
set => SetValue(CitizenshipViewModelProperty, value);
}
public static readonly PropertyData CitizenshipViewModelProperty =
RegisterProperty<MainWindowViewModel, IViewModel>(model => model.CitizenshipViewModel);
protected override async Task InitializeAsync()
{
await base.InitializeAsync();
CitizenshipViewModel = this.GetTypeFactory().CreateInstance<CitizenshipSuggestViewModel>();
}
}
}
因此,当应用程序完全加载时,特别是 SuggestModule 上的 ItemsCollection 已经填充了来自上下文的数据,在 Log 中得到了以下信息:
12:19:34:844 => [DEBUG] [Catel.MVVM.Views.ViewToViewModelMappingHelper] [1] Initializing view model container to manage ViewToViewModel mappings
12:19:34:864 => [DEBUG] [Catel.MVVM.Views.ViewToViewModelMappingHelper] [1] Initializing view model 'CitizenshipSuggestViewModel'
12:19:34:874 => [DEBUG] [Catel.MVVM.Views.ViewToViewModelMappingHelper] [1] Initialized view model 'CitizenshipSuggestViewModel'
12:19:34:895 => [DEBUG] [Catel.MVVM.Views.ViewToViewModelMappingHelper] [1] Initialized view model container to manage ViewToViewModel mappings
但是现在,如果我关注第二个文本框,它是嵌套用户控件的一部分,我有大约 5...6 秒的冻结时间。本次登录信息:
12:23:21:212 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:21:387 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:21:809 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:21:901 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:22:016 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:22:063 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:22:221 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:22:235 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:22:585 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:22:654 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:22:703 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:23:019 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:23:319 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:23:431 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:24:105 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:24:566 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:24:644 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:25:803 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
12:23:26:115 => [DEBUG] [Catel.IoC.TypeFactory] [1] Cleared type constructor cache
如何避免这种行为? 提前致谢!
- 我们建议使用 InitializeAsync 而不是数据检索的构造函数
- 您是否将 Catel 5.2 与 VS 2017 结合使用?当您 运行 没有附加调试器时,问题是否仍然出现?
使用 InitializeAsync 代替构造函数进行数据检索
使用 Orc.EntityFramework6 而不是过时的 Catel.Extensions.EntityFramework6
完全解决了我的问题。