Изменение размера столбцов списка при изменении коллекции в MVVM - PullRequest
1 голос
/ 15 октября 2019

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

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

По моей конкретной проблеме:

Я впервые создаю приложение WPF и пытаюсь обернуть головувокруг шаблона MVVM. В моем представлении у меня есть listView с сеткой. ItemSource списка просмотра связан с ICollectionView в моем ViewModel, который имеет свой CollectionViewSource, обновленный различными ObservableCollections в зависимости от того, какую категорию растений выбирает пользователь. Наблюдаемые коллекции извлекают свои данные из локальной базы данных в зависимости от ввода поискового запроса от пользователя.

Моя проблема в том, что когда пользователь впервые вводит данные для поиска, список заполняется результатами иширина каждого из столбцов gridview корректируется, чтобы соответствовать самой длинной строке в каждом столбце.

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

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

Решения, предложенные в предыдущем упомянутом посте, предлагают отредактировать мой файл xaml.cs, который, на мой взгляд, не следует делать в MVVM, поскольку файл codebehind для представления не должен содержать никакой логики. Насколько я понимаю, правильный подход состоит в том, чтобы выставить свойства в модели представления, а затем связать их с представлением через xaml.

Мой наивный подход состоял в том, чтобы выставить свойство Width в моей ViewModel, однако, поскольку у меня есть несколько столбцов в моем представлении, мне нужно было бы выставить свойства width для каждого и пересчитать их ширину путем итерации покаждый объект во вновь полученных результатах находит самую длинную строку среди них, что кажется утомительным и неправильным подходом.

Итак, мой вопрос в основном: каков наилучший способ пересчитать ширину столбцов сетки в представлении, когда ItemSource в модели представления обновляется, не имея представления модели представления о представлении?

Должен ли я выставить свойства для ширины в моей модели представления или я могу каким-то образом вызвать событие в модели представления и подписаться на это в моем представлении? Буду признателен за любую помощь или советы по этому поводу!

Вот код xaml для моего списка:

 <ListView x:Name="lvPlantCollection" ItemsSource="{Binding ActiveView}" SelectedItem="{Binding SelectedPlant}" Grid.Row="0">
                <ListView.View>
                    <GridView>
                        <GridViewColumn DisplayMemberBinding="{Binding Name}">
                            <GridViewColumnHeader Content="Navn" Tag="Name" Command="{Binding SortActiveViewByColumnCommand}" CommandParameter="{Binding RelativeSource={RelativeSource self}, Path=Tag }"></GridViewColumnHeader>
                        </GridViewColumn>
                        <GridViewColumn DisplayMemberBinding="{Binding MotherPlant.Name}">
                            <GridViewColumnHeader Content="Mor" Tag="MotherPlantName" Command="{Binding SortActiveViewByColumnCommand}" CommandParameter="{Binding RelativeSource={RelativeSource self}, Path=Tag }"></GridViewColumnHeader>
                        </GridViewColumn>
                        <GridViewColumn DisplayMemberBinding="{Binding FatherPlant.Name}">
                            <GridViewColumnHeader Content="Far" Tag="FatherPlantName" Command="{Binding SortActiveViewByColumnCommand}" CommandParameter="{Binding RelativeSource={RelativeSource self}, Path=Tag }"></GridViewColumnHeader>
                        </GridViewColumn>
                        <GridViewColumn DisplayMemberBinding="{Binding CaNumber}">
                            <GridViewColumnHeader Content="Ca nummer" Tag="CaNumber" Command="{Binding SortActiveViewByColumnCommand}" CommandParameter="{Binding RelativeSource={RelativeSource self}, Path=Tag }"></GridViewColumnHeader>
                        </GridViewColumn>
                        <GridViewColumn DisplayMemberBinding="{Binding BreedersReference}">
                            <GridViewColumnHeader Content="Breeders ref" Tag="BreedersReference" Command="{Binding SortActiveViewByColumnCommand}" CommandParameter="{Binding RelativeSource={RelativeSource self}, Path=Tag }"></GridViewColumnHeader>
                        </GridViewColumn>
                        <GridViewColumn DisplayMemberBinding="{Binding Elite}">
                            <GridViewColumnHeader Content="Elite" Tag="Elite" Command="{Binding SortActiveViewByColumnCommand}" CommandParameter="{Binding RelativeSource={RelativeSource self}, Path=Tag }"></GridViewColumnHeader>
                        </GridViewColumn>
                        <GridViewColumn Header="DNA">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <ItemsControl ItemsSource="{Binding DNA}">
                                        <ItemsControl.ItemTemplate>
                                            <DataTemplate>
                                                <TextBlock x:Name="MutationNameTxtBlock" Text="{Binding Name}" Visibility="Collapsed"></TextBlock> <!--Negated logic, set to collapsed as standard, and then only show if value if mutationscore is actually M-->
                                                <DataTemplate.Triggers>
                                                    <DataTrigger Binding="{Binding WildType}" Value="M">
                                                        <Setter TargetName="MutationNameTxtBlock" Property="Visibility" Value="Visible"></Setter>
                                                    </DataTrigger>
                                                </DataTemplate.Triggers>
                                            </DataTemplate>
                                        </ItemsControl.ItemTemplate>
                                    </ItemsControl>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                        <GridViewColumn DisplayMemberBinding="{Binding Comment}">
                            <GridViewColumnHeader Content="Kommentar" Tag="Comment" Command="{Binding SortActiveViewByColumnCommand}" CommandParameter="{Binding RelativeSource={RelativeSource self}, Path=Tag }"></GridViewColumnHeader>
                        </GridViewColumn>
                    </GridView>
                </ListView.View>
            </ListView>

И ViewModel:


public ParentMenuViewModel(DataStore ds)
{            
            IBarleyDatabaseDAO db = BarleyDatabaseMysqlDAO.Instance;
            this.ds = ds;

            DHPlants = ds.DHPlants;
            DonorPlants = ds.DonorPlants;
            BreedersReferencePlants = ds.BreedersReferencePlants;
            ElitePlants = ds.ElitePlants;
            DMIPlants = ds.DMIPlants;

            _activeView = CollectionViewSource.GetDefaultView(new List<Plant>());            
}


 ICollectionView _activeView;
        public ICollectionView ActiveView
        {
            get
            {
                return _activeView;
            }
            set
            {
                if (_activeView != value)
                {
                    _activeView = value;
                    _activeView.SortDescriptions.Clear();
                    _activeView.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
                    OnPropertyChanged("ActiveView");
                }
            }
        }

 ObservableCollection<Plant> _activeList;
        public ObservableCollection<Plant> ActiveList
        {
            get { return _activeList; }
            set
            {
                if (_activeList != value)
                {
                    _activeList = value;
                    ActiveView = CollectionViewSource.GetDefaultView(_activeList);

                    OnPropertyChanged("ActiveList");
                }
            }
        }


        public void UpdatePlants(string selectedPlantType)
        {
            if (!string.IsNullOrEmpty(Filter))
            {
                switch (selectedPlantType)
                {
                    case "CA":
                        ds.UpdatePlantList(PlantType.DH, Filter, Page * 100);
                        ActiveList = DHPlants;
                        break;

                    case "Donor":
                        ds.UpdatePlantList(PlantType.DONOR, Filter, Page * 100);
                        ActiveList = DonorPlants;
                        break;

                    case "DMI":
                        ds.UpdatePlantList(PlantType.DMI, Filter, Page * 100);
                        ActiveList = DMIPlants;                        
                        break;

                    case "Breeders Reference":
                                                ds.UpdatePlantList(PlantType.BREEDERS_REFERENCE_INTERNAL, Filter, Page * 100); 

                        ActiveList = BreedersReferencePlants;
                        break;

                    case "Elite":
                        ds.UpdatePlantList(PlantType.ELITE_INTERNAL, Filter, Page * 100); 
                        ActiveList = ElitePlants;
                        break;

                    default:
                        return;
                }
            }
            else
            {
                ds.ClearPlantCollecetions();
            }

        }
...