2016-02-03 54 views
2

我寫了一個簡單的程序與MVVM(C#)和XAML使用Caliburn.Micro庫, 但有些動作沒有工作:我如何更新ListView中的項目與Caliburn.Micro在C#中?

  • 更新項目內容
  • 獲得所選項目
  • 得到具體項目
  • 移和下移記錄
  • 啓用或禁用按鈕時添加按鈕,點擊

任何幫助,將不勝感激。

我的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(); 
     } 
    } 
} 

我的視圖模型:

// 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 
    } 
} 
+0

你是什麼意思 「上下記錄」? – StepUp

+0

@StepUp對不起,我的意思是MoveUp和Movedown。 – mohammadmot

+0

最好提出關於如何「獲得特定項目」以及如何「上移和下移記錄」的新問題,因爲它沒有足夠的關於你想要的信息。 – StepUp

回答

2

更新項目內容。 要在您的視圖中查看模型的更新項目,則應在您的模型的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)); 
     } 
    }   
} 

獲取所選項目。 保存所選項目創建視圖模型的屬性,例如File

public File SelectedFile { get; set; } 

然後綁定ListViewSelectedItem這個屬性:

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

你已經實現SelectedFile屬性後,你可以採取這樣的值:

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

單擊添加按鈕時啓用或禁用按鈕。 有兩種方法:隨着卡利和不卡利

隨着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類通過調用委託給它的中繼功能給其他對象:

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 
} 

然後創建您的視圖模型的屬性。例如:

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}"/> 
+0

非常感謝@StepUp。但我不是指如何處理點擊事件。我的意思是如何啓用(或禁用)按鈕,使其無法點擊? – mohammadmot

+0

@mohammadmot請多關注這篇文章,特別是描述'CanSayHello'方法的地方 – StepUp

+0

在我之前的問題中,你說過使用Commands來處理按鈕單擊事件,我做了你所說的並且工作。但是這次我想在窗體加載並在一條記錄添加到列表視圖後再次啓用時,在其第一個外觀中禁用按鈕。我希望我交付了這一點:) – mohammadmot

相關問題