Обновление представлений из UserControls - PullRequest
0 голосов
/ 05 марта 2020

Проблема:
Используя шаблон 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 дней с этим я не могу понять, как заставить это работать Любая идея будет очень благодарна!

...