gpt4 book ai didi

c# - MVVM 添加排序说明

转载 作者:行者123 更新时间:2023-12-03 10:36:10 26 4
gpt4 key购买 nike

我要加 Sort两个 Filters 之上的功能我已经实现了。

这就是我的代码目前的样子。
XAML

<Grid Grid.Row="1">
<StackPanel Orientation="Horizontal">
<Border BorderThickness="1" BorderBrush="Red">
<ComboBox
Name="SortComboBox"
SelectionChanged="View_SelectionChanged"
ItemsSource="{Binding sortOptions, Mode=OneWay}"
SelectedValue="{Binding selectedSortOption}"
/>
</Border>
<ComboBox
Name="GenreComboBox"
SelectionChanged="View_SelectionChanged"
ItemsSource="{Binding genreOptions, Mode=OneWay}"
SelectedValue="{Binding selectedGenreOption}"
/>
<TextBox Name="SearchTextBox" Width="154" TextChanged="Search_SelectionChanged" Text="{Binding Path=searchTerm, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</Grid>

第一个 SortComboBox习惯于 sort电影而 GenreComboBox根据流派过滤电影。 SearchTextBox是另一个按关键字查找电影的过滤器。
Behind Code
    private void View_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
_moviePanelVM.DisplayMovies.View.Refresh();
}

private void Search_SelectionChanged(object sender, TextChangedEventArgs e)
{
_moviePanelVM.DisplayMovies.View.Refresh();
}
ViewModel
 public MoviePanelViewModel()
{
...
...

this.DisplayMovies = new CollectionViewSource();
this.DisplayMovies.Source = this.Movies;
this.DisplayMovies.Filter += GenreFilter;
this.DisplayMovies.Filter += SearchFilter;
}

private void GenreFilter(object sender, FilterEventArgs e)
{
MediaDetail media = e.Item as MediaDetail;
if (selectedGenreOption != "All" && !media.genre.Contains(selectedGenreOption))
e.Accepted = false;
}

private void SearchFilter(object sender, FilterEventArgs e)
{
MediaDetail media = e.Item as MediaDetail;
if (!media.title.ToLower().Contains(searchTerm.ToLower()))
e.Accepted = false;
}
SortComboBox可能有一个选定的值 A-Z在这种情况下,我会 sort一种特殊的方式。或者它的值可能是 Z-A在这种情况下,我会 sort它是另一种方式。

我的问题是,我应该在哪里添加 SortDescriptions以及控制应该发生哪种排序以确保维持 MVVM 模式的逻辑?
UPDATE Code Behind
private void Sort_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
_moviePanelVM.SortMovies();
}

更改了我的 XAML到:
<ComboBox
Name="SortComboBox"
SelectionChanged="Sort_SelectionChanged"
ItemsSource="{Binding sortOptions, Mode=OneWay}"
SelectedValue="{Binding selectedSortOption}"
/>
ViewModel
public void SortMovies()
{
DisplayMovies.SortDescriptions.Clear();

switch (SelectedSortOption)
{
case "A-Z":
DisplayMovies.SortDescriptions.Add(new SortDescription("title", ListSortDirection.Ascending)); break;
case "Z-A":
DisplayMovies.SortDescriptions.Add(new SortDescription("title", ListSortDirection.Descending)); break;
case "Release Date":
DisplayMovies.SortDescriptions.Add(new SortDescription("year", ListSortDirection.Descending)); break;
case "Rating":
DisplayMovies.SortDescriptions.Add(new SortDescription("rating", ListSortDirection.Descending)); break;
}
}

这行得通,但我想知道我是否应该这样做?作为 filters只是 Refreshing view但与 sort我正在调用 ViewModel 中的函数.

最佳答案

我认为您不清楚 MVVM 设计模式的一些原则。理想情况下,您根本不希望 View 上有任何代码,这包括事件。

您需要用命令替换事件。 Click here for a tutorial.

在下面的示例中,我没有在 View 上使用任何事件,而是使用命令来绑定(bind)排序的更改以过滤电影。

以下是我正在使用的模型:

public class PropertyChangedBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}

public class Movie : PropertyChangedBase
{
private string _Name;

public string Name
{
get { return _Name; }
set
{
_Name = value;
OnPropertyChanged("Name");
}
}
}

这是命令:
public class SortChangedCommand : ICommand
{
MoviesViewModel _viewModel;

public SortChangedCommand(MoviesViewModel viewModel)
{
_viewModel = viewModel;
}

public bool CanExecute(object parameter)
{
return true;
}

public event EventHandler CanExecuteChanged;

public void Execute(object parameter)
{
_viewModel.Sort(parameter as string);
}
}

请注意,该命令包含对 View 模型的引用,它只是调用 排序 命令执行时的方法。

这是 View 模型:
public class MoviesViewModel : PropertyChangedBase
{
public ObservableCollection<Movie> Movies { get; set; }

private ObservableCollection<Movie> _FilteredMovies;

public ObservableCollection<Movie> FilteredMovies
{
get { return _FilteredMovies; }
set
{
_FilteredMovies = value;

//Have to implement property changed because in the sort method
//I am instantiating a new observable collection.
OnPropertyChanged("FilteredMovies");
}
}

public SortChangedCommand SortChangedCommand { get; set; }

public MoviesViewModel()
{
this.Movies = new ObservableCollection<Movie>();

#region Test Data

this.Movies.Add(new Movie()
{
Name = "Movie 1"
});

this.Movies.Add(new Movie()
{
Name = "Movie 2"
});


this.Movies.Add(new Movie()
{
Name = "Movie 3"
});

#endregion

//Copy the movies list to the filtered movies list (this list is displayed on the UI)
this.FilteredMovies = new ObservableCollection<Movie>(this.Movies);

this.SortChangedCommand = new SortChangedCommand(this);
}

public void Sort(string sortOption)
{
switch (sortOption)
{
case "A-Z": this.FilteredMovies = new ObservableCollection<Movie>(this.Movies.OrderBy(x => x.Name)); break;
case "Z-A": this.FilteredMovies = new ObservableCollection<Movie>(this.Movies.OrderByDescending(x => x.Name)); break;
}
}
}

View 模型包含两个列表,一个保存所有电影,另一个保存过滤后的电影列表。过滤后的电影将显示在 UI 上。

这是 View :
<Window x:Class="BorderCommandExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ViewModels="clr-namespace:BorderCommandExample"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ViewModels:MoviesViewModel x:Key="ViewModel"/>
</Window.Resources>
<Grid DataContext="{StaticResource ViewModel}">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>

<Button Command="{Binding SortChangedCommand}" CommandParameter="A-Z"
Content="A-Z"/>
<Button Command="{Binding SortChangedCommand}" CommandParameter="Z-A"
Content="Z-A"
Grid.Row="1"/>

<ListBox ItemsSource="{Binding FilteredMovies}"
DisplayMemberPath="Name"
Grid.Row="2"/>
</Grid>

注:我没有使用 ComboBox,因为 ComboBox 控件没有 命令 属性,但您可以轻松 get around this.

当您单击任何按钮时,该命令将执行并调用 sort 方法。然后 UI 将使用过滤后的电影进行更新。

UI 本身可能不是您所追求的,但是使用命令来实现这一点是您所需要的。

关于c# - MVVM 添加排序说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27797408/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com