Проблема:
Используя шаблон MVVM, я не могу обновить sh представления в некоторых sub-UserControls
, которые вызываются в других UserControl
.
У меня есть MainWindow
, который вызывает UserControl, он же. Container2
, с некоторыми компонентами и пустым Grid
, и все это прекрасно работает.
Мой Container2
прикрепляет в xaml
два разных вложенных представления (но скрытые), которые я хотел бы использовать следующим образом:
<UserControl x:Class="xxxx"
...
xmlns:Container3="clr-namespace:xxx"
...>
<Grid x:Name="Container2">
<Grid.Resources>
<Style x:Key="MyButtonStyle" TargetType="Button">
...
</Style>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Column="0" VerticalScrollBarVisibility="Auto">
<StackPanel>
<ItemsControl ItemsSource ="{Binding MyItemsSource}">
<ItemsControl.ItemTemplate >
<DataTemplate >
<Button Style="{StaticResource MyButtonStyle}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
<Grid Grid.Column="1">
<Container3:Container3a_View Visibility="{Binding Visibility_Container3a, FallbackValue=Collapse}"/>
<Container3:Container3b_View Visibility="{Binding Visibility_Container3b, FallbackValue=Collapse}"/>
</Grid>
</Grid>
</UserControl>
Я знаю, что вместо этого кто-то может использовать, среди прочего подходов, селектор шаблонов данных, но я подумал о том, чтобы пойти по этому пути, потому что некоторые внешние причины проектирования, которые не имеют ничего общего с этой проблемой.
В качестве упражнения для обучения оба моих под-представления выглядят одинаково и состоят на данный момент в TabControl с двумя вкладками, которые я загружаю динамически:
<UserControl x:Class="xxx.Container3a_View"
...>
<Grid x:Name="Container3a">
<Grid.Resources>
<Style x:Key="TabItemStyle" TargetType="TabItem">
<Setter Property="Header" Value="{Binding Text}"/>
<Setter Property="IsEnabled" Value="{Binding IsEnabled}"/>
</Style>
</Grid.Resources>
<TabControl ItemsSource="{Binding TabItemsSource}" ItemContainerStyle="{StaticResource TabItemStyle}"/>
</Grid>
</UserControl>
Код (каждого) подчиненного UserControl выглядит так:
public partial class Container3a_View : UserControl
{
public Container3a_View()
{
InitializeComponent();
Container3a.DataContext = new Container3a_ViewModel();
}
}
И мой ViewModel вот так:
public class Container3a_ViewModel : Container3a_Model, INotifyPropertyChanged
{
public Container3a_ViewModel()
{
// nothing here
}
public List<myObj> Container;
public myObj Tab1 = new myObj("Tab1");
public myObj Tab2 = new myObj("Tab2");
public void InitGui()
{
PrintDebug("I am here");
Container = new List<myObj>() { Tab1, Tab2 };
RaiseEvent(Container, nameof(Container));
}
public ObservableCollection<myObj> TabItemsSource
{
get => MyConverter.GetCollection(Container);
set => MyConverter.SetCollection(Container, value);
}
}
И проблема в следующем:
Когда я создаю этот код, задайте в моем основном коде одно из вложенных представлений для быть видимым и вызывать его метод InitGui()
, в сетке появляется TabControl
без вкладок и выводится отладочное предложение, что означает, что sub-userControl загружен и метод Init был вызван правильно (все нормально и как ожидается до здесь) но что загрузка вкладок и их текста не обновляется / refre sh в Gui.
Если я переместил загрузку вкладок внутрь конструктора
public Container3a_ViewModel()
{
Container = new List<myObj>() { Tab1, Tab2 };
// RaiseEvent(Container, nameof(Container)); --> not required when here
}
и повторить здание, на этот раз все показано правильно.
К сожалению, я не могу go с этим подходом, потому что в рамках этих подвидов будет много других новых компонентов, которые будут разработаны в соответствии с определенными логиками c.
I Подозреваю, я не использую правильно DataContexts или что-то еще, но после почти 2 дней с этим я не могу понять, как заставить это работать Любая идея будет очень благодарна!