c# - WPF按钮点击需要刷新一个绑定;我该怎么做呢?
问题描述
我有一个按钮:
<Button Grid.Row="2" Grid.Column="0" Command="commands:Commands.BuyComponentCommand" CommandParameter="{Binding ElementName=inventory, Path=SelectedItem}" Click="btnBuy_Click">Buy</Button>
和一个列表框:
<ListBox Name="inventory" ItemsSource="{Binding Inventory}">
...
</ListBox>
还有一些标签我想刷新单击按钮时的可见性;这是其中之一:
<TextBlock Name="txtMineralsWarning" Foreground="Yellow" Text="You don't have enough minerals to buy this component." DataContext="{Binding ElementName=inventory, Path=SelectedItem}" Visibility="{Binding Converter={StaticResource NotEnoughMineralsToVisibilityConverter}}" TextWrapping="Wrap"/>
现在的问题是,当我在ListBox
;中选择不同的项目时,标签会刷新它们的可见性。但是,当我单击按钮时,它们不会刷新其可见性,即使单击按钮会影响确定标签是否应在我的转换器中可见的状态。
这是我的转换器的转换方法,以防万一:
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var comp = (Component)value;
if (comp == null)
return Visibility.Hidden;
if (comp.Cost > PlayerShip.Instance.Savings)
return Visibility.Visible;
return Visibility.Hidden;
}
知道为什么单击按钮后转换器中测试的条件发生变化时我的标签不可见吗?我试过这个无济于事:
private void btnBuy_Click(object sender, RoutedEventArgs e)
{
txtMineralsWarning.GetBindingExpression(TextBlock.VisibilityProperty).UpdateTarget();
txtCrewWarning.GetBindingExpression(TextBlock.VisibilityProperty).UpdateTarget();
}
解决方案
你应该用 MVVM 来做
工作样本:
XAML:
<Window x:Class="WpfApp4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp4"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel>
<Button Command="{Binding ClickCommand}" Content="Click Me" />
<TextBlock Text="Label" Visibility="{Binding LabelVisibility}" />
</StackPanel>
</Window>
代码背后:
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
DataContext = new MainWindowViewModel();
}
}
视图模型:
public class MainWindowViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public ICommand ClickCommand => new RelayCommand(arg => DoExecuteClickCommand());
private void DoExecuteClickCommand() {
if (LabelVisibility == Visibility.Visible) {
LabelVisibility = Visibility.Collapsed;
} else {
LabelVisibility = Visibility.Visible;
}
OnPropertyChanged(nameof(LabelVisibility));
}
public Visibility LabelVisibility { get; set; }
}
public class RelayCommand : ICommand {
#region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion // Fields
#region Constructors
/// <summary>
/// Creates a new command that can always execute.
/// </summary>
/// <param name="execute">The execution logic.</param>
public RelayCommand(Action<object> execute)
: this(execute, null) {
}
/// <summary>
/// Creates a new command.
/// </summary>
/// <param name="execute">The execution logic.</param>
/// <param name="canExecute">The execution status logic.</param>
public RelayCommand(Action<object> execute, Predicate<object> canExecute) {
if (execute == null)
throw new ArgumentNullException("execute"); //NOTTOTRANS
_execute = execute;
_canExecute = canExecute;
}
#endregion // Constructors
#region ICommand Members
[DebuggerStepThrough]
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
}
推荐阅读
- javascript - 从列表中删除
- tidb - 当我多次运行时,相同的事务返回不同的结果
- sql - HP/Tandem TACL 如何在 SQL like 子句中使用 % 作为值
- c# - C# UWP packagemanager.UpdatePackageAsync 访问被拒绝异常
- python - 在Python中按阈值计算和计算每列的百分比
- php - 如何通过php中的新类别值重置自动增量
- google-apps-script - 库函数使用已安装的触发器生成“您无权调用 showModalDialog”错误
- node.js - 测试 - 为客户设置拒绝卡
- python - Imaplib 转发来自 gmail 的带有附件的邮件(Python)
- vb.net - PictureBox 拖放到 MS Word