我的应用程序适用于Model View ViewModel。 在我的模型中,我有一个基于我的客户端类的List。
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 :(得分:1)
您是否刚尝试将命令放入类似的属性中?:
public ICommand AddClientCommand
{
get { return new RelayCommand(AddClient, CanAddClient); }
}
public bool CanAddClient()
{
return newClient != null;
}
在CanAddClient
中放置您想要的任何逻辑,以启用或停用ICommand
。
啊......我明白了......你对RelayCommand
的执行错误了。您需要使用CanExecuteChanged
事件处理程序...您可以在GitHub上的RelayCommand.cs页面中找到正确的实现。
答案 1 :(得分:1)
我建议您使用DelegateCommands,您将在许多MVVM框架中找到此类:
public ICommand AddClientCommand
{
get
{
return new DelegateCommand(AddClient, CanExecuteAddClient);
}
}
我还看到_clients
的类型为List<Client>
。如果您将此绑定到UI以查看客户列表,除非您使用ObservableCollection<Client>
编辑:正如有人在评论中指出的那样,您应该创建_newClient
。请注意为每个添加的客户创建一个新的,或者您最终会反复添加Client
的同一个实例!