2014-01-16 53 views
0

我有适用于Model View ViewModel的应用程序。 在我的模型中,我有一个基于我的客户端类的列表。如何使用RelayCommand

public class Client 
{ 
    public string Name { get; set; } 

    public string Ip { get; set; } 

    public string Mac { get; set; } 
} 

在我的ClientRepository中,我用我的Client类从XML文件中创建一个List。

public ClientRepository() 
    { 
     var xml = "Clients.xml"; 
     if (File.Exists(xml)) 
     { 
      _clients = new List<Client>(); 
      XDocument document = XDocument.Load(xml); 
      foreach (XElement client in document.Root.Nodes()) 
      { 
       string Name = client.Attribute("Name").Value; 
       string Ip = client.Element("IP").Value; 
       string Mac = client.Element("MAC").Value; 
       _clients.Add(new Client() { Mac = Mac, Name = Name, Ip = Ip }); 
      } 
     } 
    } 

在我的UI/UX我有3个文本框1 MAC,1个IP和1名我也有一个按钮,这就是有一个结合AddClientCommand。

<Label Grid.Row="0" Grid.Column="0" Content="Host Name:"/> 
<TextBox Grid.Row="0" Grid.Column="1" x:Name="tbHostName" Height="20" Text="{Binding Path=newClient.Name, UpdateSourceTrigger=PropertyChanged}"/> 
<Label Grid.Row="1" Grid.Column="0" Content="IP Address:"/> 
<TextBox Grid.Row="1" Grid.Column="1" x:Name="tbIP" Height="20" Text="{Binding Path=newClient.Ip, UpdateSourceTrigger=PropertyChanged}"/> 
<Label Grid.Row="2" Grid.Column="0" Content="MAC Address"/> 
<TextBox Grid.Row="2" Grid.Column="1" x:Name="tbMAC" Height="20" Text="{Binding Path=newClient.Mac, UpdateSourceTrigger=PropertyChanged}"/> 
<Button Grid.Row="3" Grid.Column="0" Content="Remove" x:Name="bRemove" Margin="3 0 3 0" Click="bRemove_Click"/> 
<Button Grid.Row="3" Grid.Column="1" Content="Add" x:Name="bAdd" Margin="3 0 3 0" Click="bAdd_Click" Command="{Binding AddClientCommand}"/> 

来到我的观点:我想知道的是什么,是落实AddClientCommand的最佳方式?

什么我现在有,我知道这是行不通的:

public ClientViewModel() 
    { 
     _repository = new ClientRepository(); 
     _clients = _repository.GetClients(); 

     WireCommands(); 
    } 

    private void WireCommands() 
    { 
     AddClientCommand = new RelayCommand(AddClient); 
    } 

    public Client newClient 
    { 
     get 
     { 
      return _newClient; 
     } 
     set 
     { 
      _newClient = value; 
      OnPropertyChanged("newClient"); 
      AddClientCommand.isEnabled = true; 
     } 
    } 

    public void AddClient() 
    { 
     _repository.AddClient(newClient); 
    } 

RelayCommand类:

public class RelayCommand : ICommand 
{ 
    private readonly Action _handler; 
    private bool _isEnabled; 

    public RelayCommand(Action handler) 
    { 
     _handler = handler; 
    } 

    public bool isEnabled 
    { 
     get { return true; } 
     set 
     { 
      if (value != isEnabled) 
      { 
       _isEnabled = value; 
       if (CanExecuteChanged != null) 
       { 
        CanExecuteChanged(this, EventArgs.Empty); 
       } 
      } 
     } 
    } 

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

    public event EventHandler CanExecuteChanged; 

    public void Execute(object parameter) 
    { 
     _handler(); 
    } 
} 
+0

这是什么意思“它不工作”?你有调试吗?什么不工作? – Jviaches

+0

我新来MVVM和AddClientCommand不起作用 –

+0

当你点击按钮ADD时,是得到AddClient()方法吗? – Jviaches

回答

1

我建议你使用DelegateCommands,你会在很多MVVM框架找到这个类:

public ICommand AddClientCommand 
{ 
    get 
    { 
     return new DelegateCommand(AddClient, CanExecuteAddClient); 
    } 
} 

我也看到_clientsList<Client>类型。如果您将其绑定到UI以查看客户列表,则除非您使用ObservableCollection<Client>

,否则更改将不会被通知编辑:正如有人在评论中指出的那样,您应该创建_newClient。请注意为每个添加的客户端创建一个新的客户端,否则您最终会反复添加同一个实例Client

+0

感谢您的帮助我得到了添加项目的工作,我有一个关于如何从MVVM的DataGrid中获取所选项目的问题,您可以帮助我解决这个问题吗? –

+1

@KoenHendriks,很高兴帮助男人!在S.O.中肯定会有类似的问题,所以在发布前请检查一下。我或其他人会帮助你,以防万一你需要它,不用担心:) – Natxo

+0

再次感谢,我喜欢MVVM的工作方式,但它很混乱 –

1

你刚试图把你的命令到属性这样的事情?:

public ICommand AddClientCommand 
{ 
    get { return new RelayCommand(AddClient, CanAddClient); } 
} 

public bool CanAddClient() 
{ 
    return newClient != null; 
} 

把你想要的任何逻辑放在里面启用或禁用ICommand

Ahhhh ......我明白了......你错误地执行了RelayCommand。您需要一个使用CanExecuteChanged事件处理函数的工具...您可以在GitHub上的RelayCommand.cs页面找到正确的实现。