WPF 可排序列表视图,带有 MVVM 模式中的复选框

发布于 2024-12-10 20:47:40 字数 3865 浏览 0 评论 0原文

我有一个 WPF ListView,带有 MVVM 模式的复选框。我需要完成以下两项任务。

1)当我单击列标题时按任何列排序。如果列已经按升序排列,则应按降序重新排序,反之亦然。

2)当我选中或取消选中复选框时,SelectedTaskItem 不与 ViewModel 通信。

TaskView.xaml

 <UserControl x:Class="MyProject.TaskView"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              Height="569" Width="954" 
              HorizontalContentAlignment="Center" 
              VerticalContentAlignment="Center" 
   >


    <UserControl.Resources>
       <DataTemplate x:Key="FirstCellCheckBox">
         <CheckBox 
                Command="{Binding IsSelected, Mode= TwoWay}"
                IsChecked="{Binding Path=IsSelected, RelativeSource={RelativeSource 
                FindAncestor, AncestorType={x:Type ListViewItem}}}"
                CommandParameter="{Binding Path=SelectedTaskItem, 
                ElementName=dgTaskList, UpdateSourceTrigger=PropertyChanged}" 
                />

      </DataTemplate>

    </UserControl.Resources>
    <ListView Grid.Row="1" 
              Name="ListViewTask" 
              Margin="12,49,26,79"  
              ItemsSource="{Binding TaskList}" 
              ScrollViewer.HorizontalScrollBarVisibility="Auto"  
             >

        <ListView.View >
            <GridView x:Name="gvTaskList">
                <GridViewColumn Header="Select" 
                                CellTemplate="{StaticResource FirstCellCheckBox}" 
                                Width="30"/>

                <GridViewColumn Header="Internal File" 
                                DisplayMemberBinding="{Binding TaskID}"  
                                Width="100"/>

                <GridViewColumn Header="TaskDescription" 
                                DisplayMemberBinding="{Binding TaskDescription}"  
                                Width="100" />

                <GridViewColumn Header="Task Status" 
                                DisplayMemberBinding="{Binding TaskStatus}" 
                                Width="100" />
            </GridView>
        </ListView.View>
    </ListView> 

TaskViewModel.cs

 namespace MyProject
 {
  public class TaskViewModel: ViewModelBase
  {
    ObservableCollection<TaskModel> _TaskList;

    public TaskViewModel()
    {
         TaskDAO dal = new TaskDAO();
         _TaskList= dal.GetUpFileList();        
   }


    public ObservableCollection<TaskModel> TaskList 
    {
        get { return _TaskList; }

        set
        {
            if (_TaskList!= value)
            {
                this._TaskList= value;
                this.OnPropertyChanged("TaskList");
            }
        }
    }


    private TaskModel _selectedTaskItem;
    public TaskModel SelectedTaskItem
    {
        get { return _selectedTaskItem; }
        set
        {
            if (value != null)
            {
                _selectedTaskItem= value;
                OnPropertyChanged("SelectedTaskItem");
                if (null != _selectedTaskItem)
                {
                    ObservableCollection<TaskModel> oCol =
                        new ObservableCollection<TaskModel>();
                    foreach (TaskModel itm in TaskList)
                    {
                        if (itm.TaskID == _selectedTaskItem.TaskID)
                        {
                            itm.IsSelected = true;
                        }
                        oCol.Add(itm);

                    }
                    TaskList.Clear();
                    TaskList = oCol;
                    OnPropertyChanged("TaskList");
                }
            }

        }

    } 
  }

I have a WPF ListView with checkbox in MVVM pattern. I need to accomplish the following two tasks.

1) Sort by any column when I click on column header. If column is already in ascending order then it should reorder in descending and vice versa.

2) SelectedTaskItem is not communicating with ViewModel when i check or uncheck a checkbox.

TaskView.xaml

 <UserControl x:Class="MyProject.TaskView"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              Height="569" Width="954" 
              HorizontalContentAlignment="Center" 
              VerticalContentAlignment="Center" 
   >


    <UserControl.Resources>
       <DataTemplate x:Key="FirstCellCheckBox">
         <CheckBox 
                Command="{Binding IsSelected, Mode= TwoWay}"
                IsChecked="{Binding Path=IsSelected, RelativeSource={RelativeSource 
                FindAncestor, AncestorType={x:Type ListViewItem}}}"
                CommandParameter="{Binding Path=SelectedTaskItem, 
                ElementName=dgTaskList, UpdateSourceTrigger=PropertyChanged}" 
                />

      </DataTemplate>

    </UserControl.Resources>
    <ListView Grid.Row="1" 
              Name="ListViewTask" 
              Margin="12,49,26,79"  
              ItemsSource="{Binding TaskList}" 
              ScrollViewer.HorizontalScrollBarVisibility="Auto"  
             >

        <ListView.View >
            <GridView x:Name="gvTaskList">
                <GridViewColumn Header="Select" 
                                CellTemplate="{StaticResource FirstCellCheckBox}" 
                                Width="30"/>

                <GridViewColumn Header="Internal File" 
                                DisplayMemberBinding="{Binding TaskID}"  
                                Width="100"/>

                <GridViewColumn Header="TaskDescription" 
                                DisplayMemberBinding="{Binding TaskDescription}"  
                                Width="100" />

                <GridViewColumn Header="Task Status" 
                                DisplayMemberBinding="{Binding TaskStatus}" 
                                Width="100" />
            </GridView>
        </ListView.View>
    </ListView> 

TaskViewModel.cs

 namespace MyProject
 {
  public class TaskViewModel: ViewModelBase
  {
    ObservableCollection<TaskModel> _TaskList;

    public TaskViewModel()
    {
         TaskDAO dal = new TaskDAO();
         _TaskList= dal.GetUpFileList();        
   }


    public ObservableCollection<TaskModel> TaskList 
    {
        get { return _TaskList; }

        set
        {
            if (_TaskList!= value)
            {
                this._TaskList= value;
                this.OnPropertyChanged("TaskList");
            }
        }
    }


    private TaskModel _selectedTaskItem;
    public TaskModel SelectedTaskItem
    {
        get { return _selectedTaskItem; }
        set
        {
            if (value != null)
            {
                _selectedTaskItem= value;
                OnPropertyChanged("SelectedTaskItem");
                if (null != _selectedTaskItem)
                {
                    ObservableCollection<TaskModel> oCol =
                        new ObservableCollection<TaskModel>();
                    foreach (TaskModel itm in TaskList)
                    {
                        if (itm.TaskID == _selectedTaskItem.TaskID)
                        {
                            itm.IsSelected = true;
                        }
                        oCol.Add(itm);

                    }
                    TaskList.Clear();
                    TaskList = oCol;
                    OnPropertyChanged("TaskList");
                }
            }

        }

    } 
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

咋地 2024-12-17 20:47:40

您正在将 CheckBox 的 IsChecked 值绑定到 ListBoxItem.IsChecked,但我没有看到任何将 ListBoxItem.IsChecked 绑定到 ViewModel 的内容。

尝试将以下内容添加到您的 ListBox.Resources

<Style TargetType="{x:Type ListBoxItem}">
    <Setter Property="IsSelected" Value="{Binding IsSelected}" />
</Style>

对于排序,我建议使用 DataGrid 而不是 ListView,因为排序是内置于 DataGrid 中的。如果您不想这样做,您可能需要制作一些自定义 ListViewHeaders 来在 ViewModel 中执行 SortCommand

You are binding the CheckBox's IsChecked value to ListBoxItem.IsChecked, but I don't see anything that binds ListBoxItem.IsChecked to your ViewModel.

Try adding the following to your ListBox.Resources

<Style TargetType="{x:Type ListBoxItem}">
    <Setter Property="IsSelected" Value="{Binding IsSelected}" />
</Style>

For sorting, I'd recommend using a DataGrid instead of a ListView, since sorting is built into the DataGrid. If you don't want to do that, you'll probably have to make some custom ListViewHeaders which execute a SortCommand in your ViewModel

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文