c# - 动态控制可见性 WPF MVVM C#
问题描述
我有一个列表框,下面有几个按钮。
<ListBox ItemsSource="{Binding SongList}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=.}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel Orientation="Horizontal">
<Button Content="Add" Command="{Binding addSongCommand}" />
<Button Content="Remove"/>
</StackPanel>
当我单击添加按钮时,我希望将添加和删除按钮替换为文本框并提交按钮。
然后,当我单击提交时,我希望它将输入的字符串添加到集合(SongList)中并带回添加和删除按钮。
如何使用 MVVM 完成控件的隐藏和显示?假设我可以在 addSongCommand.Execute() 方法中访问这个视图视图模型,我会在那里放置什么逻辑?
public class AddSongCommand : CommandBase
{
private ViewModelBase _vm;
public AddSongCommand(ViewModelBase vm)
{
_vm = vm;
}
public override bool CanExecute(object parameter) => true;
public override void Execute(object parameter)
{
// what goes here?
}
}
解决方案
<ListBox ItemsSource="{Binding SongList}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=.}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel Orientation="Horizontal" Visibility="{Binding IsAdding, Converter={booltovisflipconverter}}">
<Button Content="Add" Command="{Binding AddSongCommand}" />
<Button Content="Remove"/>
</StackPanel>
<StackPanel Orientation="Vertical" Visibility="{Binding IsAdding, Converter={booltovisconverter}}">
<TextBox Text="{Binding Song}"/>
<Button Content="Submit" Command="{Binding SubmitSongCommand}" />
</StackPanel>
注意:您需要编写转换器来翻转可见性,或使用数据触发器。
public class ViewModel : ViewModelBase
{
public ObservableCollection<string> SongList {get;set;} = new ObservableCollection<string>();
public bool IsAdding
{
get { ... }
set { notifychanged }
}
public string Song
{
get { ... }
set { notifychanged }
}
// called from add song command
public void EnableAdding()
{
IsAdding = true;
}
// called from submit command
public void SubmitSong()
{
SongList.Add(Song);
IsAdding = false;
}
}
public class SubmitSongCommand : CommandBase
{
private ViewModel _vm;
public SubmitSongCommand(ViewModel vm)
{
_vm = vm;
}
public override bool CanExecute(object parameter) => true;
public override void Execute(object parameter)
{
_vm.SubmitSong();
}
}
public class AddSongCommand : CommandBase
{
private ViewModel _vm;
public AddSongCommand(ViewModel vm)
{
_vm = vm;
}
public override bool CanExecute(object parameter) => true;
public override void Execute(object parameter)
{
_vm.EnableAdding();
}
}
上面为每个命令使用了特定的类型。这么多命令=许多类型。您可以改为使用委托来实现基本命令。
public class SimpleCommand : ICommand
{
public Action<object> ExecuteAction {get;set;}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
ExecuteAction?.Invoke(parameter);
}
}
public class ViewModel
{
public ViewModel()
{
AddSongCommand = new SimpleCommand()
{
ExecuteAction = (x) => { AddSong(); }
};
SubmitSongCommand = new SimpleCommand()
{
ExecuteAction = (x) => { SubmitSong(); }
};
}
public ICommand AddSongCommand { get; }
public ICommand SubmitSongCommand { get; }
public void AddSong()
{
// add song to list
}
public void SubmitSong()
{
// submit song
}
}
推荐阅读
- flutter - 如何将一个函数传递给另一个函数,并在 Dart 中设置了可选参数?
- sql - 如何编写一个 JPQL 查询来查找此连接中未找到的记录?
- php - 指定算术运算符的控制结构
- javascript - Firebase 实时数据库的快照不完整/缺少几层
- angular - Jhipster下载过程中如何更改文件名(java + angular)
- python - 无法发送多封电子邮件,因为我被中止(断开连接)
- firebase - 已完成的 firebase 函数中的异步调用会发生什么?
- php - php simplexml元素属性特定值
- javascript - (显示更多)/(显示更少)按钮 VueJS 中的问题
- java - java - 如何在java中将字符串x.*y拆分为x和y?