WPF对观测值分类的分类可去选择一个组合



我有一个组合,用户可以在其中选择他们正在从事的jobtype。Combobox具有AllJobTypes的列表。问题源于用户何时添加新的JobType,我将JobType添加到AllJobTypes ObservableCollection中,然后对其进行排序。当分类发生时,Combobox获得了De of的选择,并且不确定为什么。JobConfig.SelectedJobType.name在此过程中永远不会更改。有没有办法对可观察到的收藏进行分类,但它不会破坏ComboBox?

public class JobTypeList : ObservableCollection<JobType> {
  public void SortJobTypes() {
    var sortableList = new List<JobType>(this);
    sortableList.Sort((x, y) => x.Name.CompareTo(y.Name));
    //this works but it creates a bug in the select for JobTypes
    for (int i = 0; i < sortableList.Count; i++) {
        this.Move(this.IndexOf(sortableList[i]), i);
    }
  }

和xaml

<ComboBox Grid.Column="0" SelectionChanged="JobTypeComboBox_SelectionChanged"
                              Name="JobTypeComboBox"
                              ItemsSource="{Binding Path=AllJobTypes}"
                              DisplayMemberPath="Name"
                              SelectedValuePath="Name"
                              SelectedValue="{Binding 
Path=JobConfig.SelectedJobType.Name}" />

而不是在视图模型中对集合进行排序,而是将Combobox的物品插入到CollectionViewSource,您可以在其中指定SortDescription

<Window ...
    xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
    ...>
    <Window.Resources>
        <CollectionViewSource x:Key="cvs" Source="{Binding AllJobTypes}">
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription PropertyName="Name"/>
            </CollectionViewSource.SortDescriptions>
        </CollectionViewSource>
    </Window.Resources>
    ...
    <ComboBox ItemsSource="{Binding Source={StaticResource cvs}}"
              DisplayMemberPath="Name"
              SelectedValuePath="Name"
              SelectedValue="{Binding JobConfig.SelectedJobType.Name}"/>
    ...
</Window>

有关更多信息,请参阅如何:使用XAML中的视图对数据进行分类和分组数据。

这是使用itemssource/selectedItem的版本。请注意,您可以将新项目添加到列表中并对其进行排序,而不会在视图中丢失当前选择的项目。

窗口

<Window
    x:Class="SortingAList.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:SortingAList"
    mc:Ignorable="d"
    Title="MainWindow"
    Height="350"
    Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <TextBox
            Text="{Binding NewJobType, Delay=1000}"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            Width="200" />
        <ComboBox
            Grid.Row="1"
            ItemsSource="{Binding JobTypes}"
            SelectedItem="{Binding SelectedJobType}"
            DisplayMemberPath="Name"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            Width="200" />
    </Grid>
</Window>

代码

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ViewModel();
    }
}
public class Notifier : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void Notify([CallerMemberName]string property = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
    }
}
public class ViewModel : Notifier
{
    private JobType _selectedJobType;
    private string _newJobType;
    public JobTypeList JobTypes { get; private set; } 
    public JobType SelectedJobType { get => _selectedJobType; set { _selectedJobType = value; Notify(); } }
    public string NewJobType { get => _newJobType; set { _newJobType = value; Notify(); AddNewJobType(value); } }
    public ViewModel()
    {
        JobTypes = new JobTypeList();
        JobTypes.Add(new JobType { Name = "Butcher" });
        JobTypes.Add(new JobType { Name = "Baker" });
        JobTypes.Add(new JobType { Name = "LED maker" });
    }
    private void AddNewJobType(string name)
    {
        if(JobTypes.Any(x => x.Name == name)) return;
        JobTypes.Add(new JobType { Name = name });
        JobTypes.SortJobTypes();
    }
}
public class JobType : Notifier
{
    private string _name;
    public string Name { get => _name; set { _name = value; Notify(); } }
}

使用您的JobTypeslist

public class JobTypeList : ObservableCollection<JobType>
{
    public void SortJobTypes()
    {
        var sortableList = new List<JobType>(this);
        sortableList.Sort((x, y) => x.Name.CompareTo(y.Name));
        //this works but it creates a bug in the select for JobTypes
        for(int i = 0; i < sortableList.Count; i++)
        {
            this.Move(this.IndexOf(sortableList[i]), i);
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新