c# - 如何在 C# 中使用 Caliburn.Micro 更新 ListView 中的项目?

标签 c# listview caliburn.micro

我使用 Caliburn.Micro 库使用 MVVM (C#) 和 XAML 编写了一个简单的程序, 但有些操作不起作用:

  • 更新项目内容
  • 获取所选项目
  • 获取特定项目
  • 上移和下移记录
  • 单击“添加”按钮时启用或禁用按钮

如有任何帮助,我们将不胜感激。

我的 GUI 代码:

// Views\MainView.xaml
<Window x:Class="ListBox_CaliburnMicro.MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro"
        xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        xmlns:vm="clr-namespace:ListBox_CaliburnMicro"
        WindowStartupLocation="CenterScreen"
        Title="MainWindow" Height="300" Width="600">
    <Grid>
        <Grid.DataContext>
            <vm:MainViewModel/>
        </Grid.DataContext>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="153*"/>
        </Grid.ColumnDefinitions>

        <Button Content="Add" Command="{Binding AddCommand}" Grid.Column="1" HorizontalAlignment="Left" Margin="10,37,0,0" VerticalAlignment="Top" Width="75" ToolTip="Add item end of list" Background="White" Foreground="Black" Height="22"/>
        <Button Content="Delete" Command="{Binding DeleteCommand}" Grid.Column="1" HorizontalAlignment="Left" Margin="96,37,0,0" VerticalAlignment="Top" Width="75" ToolTip="Delete first item from list" Background="White" Foreground="Black" Height="22"/>
        <Button Content="Update" Command="{Binding UpdateCommand}" Grid.Column="1" HorizontalAlignment="Left" Margin="184,37,0,0" VerticalAlignment="Top" Width="75" ToolTip="Update first item from list" Background="White" Foreground="Black" Height="22"/>
        <Button Content="GetSelectedItem" Command="{Binding GetSelectedItemCommand}" Grid.Column="1" HorizontalAlignment="Left" Margin="271,37,0,0" VerticalAlignment="Top" Width="95" ToolTip="get selected item from list" Background="White" Foreground="Black" Height="22"/>
        <Button Content="GetItem:" Command="{Binding GetItemXCommand}" Grid.Column="1" HorizontalAlignment="Left" Margin="377,37,0,0" VerticalAlignment="Top" Width="75" ToolTip="get item x, from list" Background="White" Foreground="Black" Height="22"/>

        <TextBox Grid.Column="1" x:Name="ItemX" Text="0" HorizontalAlignment="Left" Height="24" Margin="457,35,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="70"/>

        <ListView Grid.Column="1" x:Name="FileListView" ItemsSource="{Binding Path=Files}" VerticalAlignment="Stretch" HorizontalContentAlignment="Stretch" Margin="10,65,10,10" Foreground="Black" Background="#FFE6EEF7">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Status" Width="Auto"
                    DisplayMemberBinding="{Binding FileStatus}"/>
                    <GridViewColumn Header="Name" Width="Auto"
                    DisplayMemberBinding="{Binding FileName}"/>
                    <GridViewColumn Header="Size" Width="Auto"
                     DisplayMemberBinding="{Binding FileSize}"/>
                    <GridViewColumn Header="System Type" Width="Auto"
                    DisplayMemberBinding="{Binding FileType}"/>
                    <GridViewColumn Header="Email Count" Width="Auto"
                     DisplayMemberBinding="{Binding FileEmailCount}"/>
                    <GridViewColumn Header="Info Count" Width="Auto"
                     DisplayMemberBinding="{Binding FileInfoCount}"/>
                </GridView>
            </ListView.View>
        </ListView>

    </Grid>
</Window>

我的模型是:

// Model\File.cs
using System;

namespace ListBox_CaliburnMicro.Model
{
    public class File
    {
        private Guid _FileID;
        public Guid FileID
        {
            get
            {
                return _FileID;
            }
            set 
            {
                _FileID = value;
            }
        }
        public string FileStatus { get; set; }
        public string FileName { get; set; }
        public string FileSize { get; set; }
        public string FileType { get; set; }
        public string FileEmailCount { get; set; }
        public string FileInfoCount { get; set; }

        public File()
        {
            FileID = Guid.NewGuid();
        }
        public File(string s1 = "", string s2 = "", string s3 = "", string s4 = "", string s5 = "", string s6 = "")
        {
            FileID = Guid.NewGuid();

            FileStatus = s1;
            FileName = s2;
            FileSize = s3;
            FileType = s4;
            FileEmailCount = s5;
            FileInfoCount = s6;
        }
    }
}

我的命令处理程序代码:

// ViewModels\CommandHandler.cs
using System;
using System.Windows.Input;

namespace ListBox_CaliburnMicro.ViewModels
{
    public class CommandHandler : ICommand
    {
        private System.Action _action;
        private bool _canExecute;
        public CommandHandler(System.Action action, bool canExecute)
        {
            _action = action;
            _canExecute = canExecute;
        }
        public bool CanExecute(object parameter)
        {
            return _canExecute;
        }

        public event EventHandler CanExecuteChanged;
        public void Execute(object parameter)
        {
            _action();
        }
    }
}

还有我的 ViewModel:

// ViewModels\MainViewModel.cs
using Caliburn.Micro;
using ListBox_CaliburnMicro.Model;
using ListBox_CaliburnMicro.ViewModels;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace ListBox_CaliburnMicro
{
    public class MainViewModel : Screen, INotifyPropertyChanged
    {
        public MainViewModel()
        {
            FillDataFile();

            _canAddCommandExecute = true;
            _canDeleteCommandExecute = false;
            _canUpdateCommandExecute = false;
            _canGetSelectedItemCommandExecute = false;
            _canGetItemXCommandExecute = false;
        }

        #region File listView
        private ObservableCollection<File> _Files;
        public ObservableCollection<File> Files
        {
            get { return _Files; }
            set 
            {
                _Files = value;
                OnPropertyChanged("Files");
            }
        }

        private void FillDataFile()
        {
            _Files = new ObservableCollection<File>();
            for (int i = 0; i < 0; i++)
            {
                _Files.Add(new File() { FileStatus = "status", FileName = "name", FileSize = "size", FileType = "type", FileEmailCount = "email_count", FileInfoCount = "info_count" });
            }
        }

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

        #region ItemX textbox
        private string _ItemX = "0";
        public string ItemX
        {
            get 
            {
                return _ItemX;
            }
            set 
            {
                _ItemX = value;
            }
        }
        #endregion

        #region command button

        #region Add button with Command
        private ICommand _AddCommand;
        public ICommand AddCommand
        {
            get
            {
                return _AddCommand ?? (_AddCommand = new CommandHandler(() => AddAction(), _canAddCommandExecute));
            }
        }

        static int nIndex = 0;

        private bool _canAddCommandExecute;
        public void AddAction()
        {
            string strName = string.Format("{0}", nIndex++);
            _Files.Add(new File() { FileStatus = "status", FileName = strName, FileSize = "size", FileType = "type", FileEmailCount = "email_count", FileInfoCount = "info_count" });

            // enabled action buttons,
            // !!! but not worded !!!
            _canAddCommandExecute = true;
            _canDeleteCommandExecute = true;
            _canUpdateCommandExecute = true;
            _canGetSelectedItemCommandExecute = true;
            _canGetItemXCommandExecute = true;


        }
        #endregion

        #region Delete button with Command
        private ICommand _DeleteCommand;
        public ICommand DeleteCommand
        {
            get
            {
                return _DeleteCommand ?? (_DeleteCommand = new CommandHandler(() => DeleteAction(), _canDeleteCommandExecute));
            }
        }

        private bool _canDeleteCommandExecute;
        public void DeleteAction()
        {
            if (_Files.Count > 0)
                _Files.RemoveAt(0);
        }
        #endregion

        #region Update button with Command
        private ICommand _UpdateCommand;
        public ICommand UpdateCommand
        {
            get
            {
                return _UpdateCommand ?? (_UpdateCommand = new CommandHandler(() => UpdateAction(), _canUpdateCommandExecute));
            }
        }

        private bool _canUpdateCommandExecute;
        public void UpdateAction()
        {
            if (_Files.Count > 0)
            {
                // update FileName field
                _Files[0].FileName = "+"; // !!! but didn't work !!!

                // List<File> FilesSelect = _Files.Where(p => p.FileID == _Files[0].FileID).ToList();
            }
        }
        #endregion

        #region GetSelectedItem button with Command
        private ICommand _GetSelectedItemCommand;
        public ICommand GetSelectedItemCommand
        {
            get
            {
                return _GetSelectedItemCommand ?? (_GetSelectedItemCommand = new CommandHandler(() => GetSelectedItemAction(), _canGetSelectedItemCommandExecute));
            }
        }

        private bool _canGetSelectedItemCommandExecute;
        public void GetSelectedItemAction()
        {
            if (_Files.Count > 0)
            {
                // ... get selected item in ListView
            }
        }
        #endregion

        #region GetItemX button with Command
        private ICommand _GetItemXCommand;
        public ICommand GetItemXCommand
        {
            get
            {
                return _GetItemXCommand ?? (_GetItemXCommand = new CommandHandler(() => GetItemXAction(), _canGetItemXCommandExecute));
            }
        }

        private bool _canGetItemXCommandExecute;
        public void GetItemXAction()
        {
            if (_Files.Count > 0)
            {
                // ... get item 'X' that enter in TextBox control
            }
        }
        #endregion

        #endregion
    }
}

最佳答案

更新项目内容。 要在 View 中查看模型的更新项,您应该在模型的 EACH 属性中实现 INotifyPropertyChanged 事件。例如:

public class File:INotifyPropertyChanged
{
    private Guid _FileID;
    public Guid FileID
    {
        get
        {
            return _FileID;
        }
        set 
        {
            _FileID = value;
            OnPropertyChanged("FileID");
        }
    }

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

获取所选项目。 在 ViewModel 中创建一个属性来保存所选项目,例如 File:

public File SelectedFile { get; set; }

然后将 ListViewSelectedItem 绑定(bind)到此属性:

<ListView Name="UserGrid" SelectedItem="{Binding SelectedFile}"  
 ItemsSource="{Binding Path=Files}"/>

实现 SelectedFile 属性后,您可以获取如下值:

if(SelectedFile!=null)
    var exactFile=SelectedFile;

单击“添加”按钮时启用或禁用按钮。 有两种方法:使用 Caliburn 和不使用 Caliburn

使用 CaliburnMicro: CaliburnMicro 有自己的机制来处理按钮 Click 事件。例如:

<Button Content="ShowPageTwo">
     <i:Interaction.Triggers>
         <i:EventTrigger EventName="Click">
              <cal:ActionMessage MethodName="ShowPageTwo" />
         </i:EventTrigger>
     </i:Interaction.Triggers>
</Button>

要查看有关实现的更多详细信息,请参阅official guide at CodePlex .

没有 CaliburnMicro:

首先,您应该创建 RelayCommand 类,通过调用委托(delegate)将其功能转发给其他对象:

public class RelayCommand : ICommand
{
    #region Fields

    readonly Action<object> _execute;
    readonly Predicate<object> _canExecute;

    #endregion // Fields

    #region Constructors

    public RelayCommand(Action<object> execute)
        : this(execute, null)
    {
    }

    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");

        _execute = execute;
        _canExecute = canExecute;
    }
    #endregion // Constructors

    #region ICommand Members

    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute(parameter);
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public void Execute(object parameter)
    {
        _execute(parameter);
    }

    #endregion // ICommand Members
}

然后在您的 viewModel 中创建一个属性。例如:

public class YourViewModel
{
    public RelayCommand YourCommand { get; set; }
    public YourViewModel()
    {
        YourCommand = new RelayCommand(DoSmth, CanDoSmth);
    }

    private void DoSmth(object obj)
    {
        Message.Box("Hello from viewModel"); 
    }

    private bool CanDoSmth(object obj)
    {
       //you could implement your logic here. But by default it should be  
       //set to true
       return true;
    }
}

XAML 应该如下所示:

<Button Content="Click me!" Command="{Binding LoginCommand}"/> 

关于c# - 如何在 C# 中使用 Caliburn.Micro 更新 ListView 中的项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35174319/

相关文章:

c# - 单一职责 vs 封装

android - 在选项卡式 Activity 中将 sqlite 数据库中的所有数据显示到 ListView 中

java - Baseadapter 中的 Android Listview 如何保存对列表的更改

wpf - 将所选项目作为参数发送到 View 模型中的方法 [WPF、Caliburn]

wpf - 将 EF4 与 Caliburn.Micro 绑定(bind) : Should I expose my Entity as a property of the ViewModel?

c# - asp.net 5 MVC 6 web api访问现有数据库

c# - Closedxml:无法下载文件并立即通过邮件发送

c# - 如何指定一个子元素在全局命名空间中?

android - 从 SQLite 数据库填充 ListView

c# - Caliburn Micro WPF 窗口管理