在我的MVVM应用程序中,当我使用静态方法创建视图模型以从商店加载数据并获得通知时,当通知从商店到达时,视图不会更新。商店使用Lazy类。
当我第一次加载视图模型时会发生什么,首先调用静态视图模型构造器,然后调用OnCodeTypesLoaded。但是当我在视图模型之间切换时,视图会正确显示,就像预期的那样。我发现的一个解决方案是在XAML绑定中将IsAsync设置为true,然而,我认为这不是一个好的解决方案,因为它看起来很不稳定。我有视图模型的OnPropertyChanged属性。
依赖性注入
services.AddSingleton<CreateViewModel<ProductViewModel>>(services => () => CreateProductViewModel(services));
private static ProductViewModel CreateProductViewModel(IServiceProvider services)
{
return ProductViewModel.LoadProduct(services.GetRequiredService<IProductEndpoint>(),services.GetRequiredService<ICodeTypesStore>());
}
产品视图模型
public class ProductViewModel : ViewModelBase
{
private readonly IProductEndpoint _productEndpoint;
private readonly ICodeTypesStore _codeTypesStore;
public ProductViewModel(IProductEndpoint productEndpoint, ICodeTypesStore codeTypesStore)
{
_productEndpoint = productEndpoint;
_codeTypesStore = codeTypesStore;
_codeTypesStore.CodeTypesLoaded += OnCodeTypesLoaded;
LoadProductCommand = new LoadProductCommand(this, productEndpoint);
LoadCodeTypesCommand = new LoadCodeTypesCommand(codeTypesStore);
}
private void OnCodeTypesLoaded()
{
SystemTypes = _codeTypesStore.SystemTypes(SistemTypes.IT_Management);
Product.SetNonExistantIdentifiers(SystemTypes);
}
public ICommand LoadProductCommand { get; }
public ICommand LoadCodeTypesCommand { get; }
public static ProductViewModel LoadProduct(IProductEndpoint productEndpoint, ICodeTypesStore codeTypesStore)
{
ProductViewModel viewModel = new ProductViewModel(productEndpoint,codeTypesStore);
viewModel.LoadProductCommand.Execute(null);
viewModel.LoadCodeTypesCommand.Execute(null);
return viewModel;
}
}
显示产品类别
public class DisplayProduct : UI.Product
{
public DisplayProduct(){}
private List<UI.Sistem> _systems;
public List<UI.Sistem> NonExistantIdentifiers { get; private set; }
public DisplayProduct(UI.Product prd): base(prd.ID,prd.Name,prd.IsCompra,prd.IsProducao,prd.IsVenda,prd.Identifiers)
{
}
public void SetNonExistantIdentifiers(List<UI.Sistem> systems)
{
_systems = systems;
SetNonExistantIdentifiers();
}
private void SetNonExistantIdentifiers()
{
NonExistantIdentifiers = _systems.Where(s => !base.Identifiers.Select(x => x.System.ID).ToList().Contains(s.ID)).ToList();
}
}
用户控制产品未加载
<UserControl x:Class="WPFStuff.Controls.ProductIDsNonLoaded"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WPFStuff.Controls"
xmlns:helpers="clr-namespace:WPFStuff.Helpers"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<ItemsControl ItemsSource="{Binding NonExistantIdentifiers}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<WrapPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Label"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}"/>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Value"/>
</Grid.ColumnDefinitions>
<TextBox MinWidth="150" helpers:SelectAllFocusBehavior.Enable="True">
<TextBox.Resources>
<helpers:BindingProxy x:Key="TargetProxy2" Data="{Binding RegExpression}"/>
</TextBox.Resources>
<TextBox.Text>
<Binding Path="Name" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<helpers:CodeTypeValidationRule>
<helpers:CodeTypeValidationRule.CodeTypePattern>
<helpers:CodeTypeValidationParameter RegExPattern="{Binding Data, Source={StaticResource TargetProxy2}}"/>
</helpers:CodeTypeValidationRule.CodeTypePattern>
</helpers:CodeTypeValidationRule>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</Grid>
</WrapPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
ProductView
<UserControl x:Class="WPFStuff.Views.ProductView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WPFStuff.Views"
xmlns:controls="clr-namespace:WPFStuff.Controls" xmlns:helpers="clr-namespace:WPFStuff.Helpers"
mc:Ignorable="d"
FontSize="20"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<controls:Product DataContext="{Binding Product}" />
<WrapPanel Grid.IsSharedSizeScope="True" Grid.Row="1">
<controls:ProductsIDs DataContext="{Binding Product}" />
<controls:ProductIDsNonLoaded DataContext="{Binding Product}"/>
</WrapPanel>
</Grid>
CodeTypesStore
public class CodeTypesStore : ICodeTypesStore
{
private readonly ICodeTypesEndpoint _codeTypesEndpoint;
private readonly List<UI.Sistem> _systemCodeTypes;
private readonly List<UI.CodeType> _productCodeTypes;
private Lazy<Task> _loadCodeTypesLazy;
public event Action CodeTypesLoaded;
public CodeTypesStore(ICodeTypesEndpoint codeTypesEndpoint)
{
_codeTypesEndpoint = codeTypesEndpoint;
_productCodeTypes = new();
_systemCodeTypes = new();
_loadCodeTypesLazy = CreateLoadCodeTypes();
}
private bool _isLoading;
public bool IsLoading
{
get { return _isLoading; }
set { _isLoading = value; }
}
public async Task LoadCodeTypes()
{
await _loadCodeTypesLazy.Value;
CodeTypesLoaded?.Invoke();
}
private Lazy<Task> CreateLoadCodeTypes()
{
return new Lazy<Task>(() => InitializeCodeTypes());
}
private async Task InitializeCodeTypes()
{
IEnumerable<UI.Sistem> s = await _codeTypesEndpoint.GetSystemTypesCodes();
IEnumerable<UI.CodeType> c = await _codeTypesEndpoint.GetProductsCodeTypes();
_systemCodeTypes.Clear();
_productCodeTypes.Clear();
_systemCodeTypes.AddRange(s);
_productCodeTypes.AddRange(c);
//CodeTypesLoaded?.Invoke();
}
public List<UI.Sistem> SystemTypes(SistemTypes systemTypes)
{
return _systemCodeTypes.Where(sct => sct.SystemType?.SystemTypes == systemTypes).ToList();
}
public IEnumerable<UI.CodeType> ProductCodeTypes => _productCodeTypes;
}
1条答案
按热度按时间gdx19jrr1#
我解决了这个问题,我在DisplayProduct类中将List更改为ObservableCollection