Пользовательский элемент управления в другом пользовательском элементе управления получает мусор в WPF - PullRequest
0 голосов
/ 07 ноября 2018

У меня есть окно с меню и контролем контента. Когда я загружаю модуль, он проверяет, открыт ли этот модуль, если нет, то создает его, добавляет в коллекцию модулей и делает его текущим активным. Они настроены так:

MainWindowViewModel.cs

private void ChangeViewModel(Object parameter)
{
    string name = (string) parameter;

    IPageViewModel page;

    if (PageViewModels.FirstOrDefault(vm => vm.Name == name) != null)
    {
        CurrentPageViewModel = PageViewModels
            .FirstOrDefault(vm => vm.Name == name);
    }
    else
    {
        if (name == "TimeSheets")
        {
            page = new TimeSheetViewModel();
        }
        else if (name == "Test")
        {
             page = new TestViewModel();
        }
        else
        {
            page = new HomeViewModel();
        }

        CurrentPageViewModel = page;
        PageViewModels.Add(page);
    }
}

MainWindow.xaml

<Window.Resources>
    <DataTemplate DataType="{x:Type local:HomeViewModel}">
        <local:Home />
    </DataTemplate>
    <DataTemplate DataType="{x:Type local:TimeSheetViewModel}">
        <local:Timesheet />
    </DataTemplate>
    <DataTemplate DataType="{x:Type local:TestViewModel}">
        <local:Test />
    </DataTemplate>
</Window.Resources>
<Grid x:Name="gridContent" Margin="70,42,20,20" >
    <ContentControl Content="{Binding CurrentPageViewModel}" />
</Grid>

Кажется, это работает для переключения между модулями / страницами, но на одной странице у меня есть пользовательский элемент управления, который имеет свой собственный текст данных, и он получает мусор каждый раз, когда я покидаю эту страницу, и повторно создается, когда я возвращаюсь на страницу. .

TimeSheet.xaml

<Grid>
    <local:EmployeeList />
</Grid>

EmployeeList.xaml

<UserControl.DataContext>
    <local:EmployeeListViewModel/>
</UserControl.DataContext>
<Grid>
    <Grid.Background>
        <SolidColorBrush Color="{StaticResource LIGHT_Main}"/>
    </Grid.Background>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="1*"/>
    </Grid.RowDefinitions>
    <Grid Grid.Row="0" Margin="5">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Label Grid.Column="0" Content="Search "/>
        <TextBox Grid.Column="1" Text="{Binding SearchParameter, UpdateSourceTrigger=PropertyChanged}" Margin="4,0,4,0"/>
        <Image Grid.Column="2" Source="pack://application:,,,/Images/Icons/SearchTiny.png" Margin="5,0,8,0"/>
    </Grid>
    <Grid Grid.Row="1" Margin="6">
        <DataGrid x:Name="gridEmployees" ItemsSource="{Binding EmployeesFiltered}" MaxHeight="500"  VerticalAlignment="Stretch" AutoGenerateColumns="False" CanUserReorderColumns="False" CanUserSortColumns="False"  HorizontalGridLinesBrush="{StaticResource GridLines}" VerticalGridLinesBrush="{StaticResource GridLines}" SelectionMode="Single" IsReadOnly="True" Width="Auto">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}" IsReadOnly="True" Width="200"/>
                <DataGridTextColumn Header="Badge" Binding="{Binding Badge}" IsReadOnly="True" Width="1*"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Grid>

Поэтому, когда он загружается, я могу искать список сотрудников, который работает нормально, но как только я загружаю другой модуль, сборщик мусора забирает мои параметры поиска и список сотрудников, поэтому он должен перезагрузить их. Если я сделаю текст данных EmployeeList.xaml таким же, как TimeSheet.xaml, и добавлю обязательные поля, я не теряю свой параметр поиска при переключении между модулями, но EmployeeList - это элемент управления, который я хотел бы использовать в нескольких местах в моей программе, так что было бы неплохо иметь свой собственный текст данных.

Дайте мне знать, если это не имеет смысла, или мой подход неверен.

Спасибо!

1 Ответ

0 голосов
/ 07 ноября 2018

Я не считаю, что все элементы управления обязательно должны иметь свои собственные виртуальные машины. Обычно я кодирую, что страница имеет виртуальную машину, и эти значения передаются отдельным свойствам зависимостей в элементах управления.

Если у вас есть данные, которые должны быть разделены между несколькими элементами управления, то эти данные должны существовать только на одной виртуальной машине и передаваться как свойство (и) зависимости как таковое.


Но ... кроме того, я хотел бы иметь эти VMS в качестве свойств основной виртуальной машины, и каждый из данных datacontext автоматически наследует родительский datacontext .... Что на этом этапе позволяет получить правильные данные для каждого элемента управления затем станет упражнением в привязке (маршрутизации) к нужному месту на исходной виртуальной машине.

...