XAML - 更新不同属性更新时的文本

本文关键字:更新 属性 文本 XAML | 更新日期: 2023-09-27 18:35:56

所以我有以下 XAML:

<TextBlock Text="{Binding DisconnectedDevices, UpdateSourceTrigger=PropertyChanged}" />

视图模型具有以下属性:

public string DisconnectedDevices {get; set;}
public IEnumerable<IDeviceInformationVM> DeviceCollection {get; set;}

有一个被调用的方法会引发属性通知事件:

public void DeviceCollectionChanged()
{
    RaisePropertyChanged(() => DeviceCollection);
}

我想在设备集合更改时更新文本块中的值。 我知道我可以在断开连接的设备上调用 RaisePropertyChanged,但我想知道是否可以在不同的属性更改事件上更新 TextBlock。

谢谢大家!

编辑:感谢您建议使用ObservableCollection而不是IEnumerable,不幸的是,我不能自由更改集合类型。

每当集合更改时都会调用 DeviceCollectionChanged 方法(我知道这很乏味......

进一步编辑:刚刚继续

RaisePropertyChanged(() => DisconnectedDevices);

我很感激问题中可能没有提供足够的信息来了解我想要做的事情,对此深表歉意

XAML - 更新不同属性更新时的文本

我不确定您当前的代码是否有效,但假设它有效。为什么不使用 - ObservableCollection<IDeviceInformationVM>而不是IEnumerable<IDeviceInformationVM> DeviceCollection您将不需要 DeviceCollectionChanged 事件。会照顾的。

是的,您可以提高

public void DeviceCollectionChanged()
{
    RaisePropertyChanged(() => DeviceCollection);
    RaisePropertyChanged(() => DisconnectedDevices);
   // or RaisePropertyChanged("DisconnectedDevices"); Whichever works
}

请参阅此问题,它可能会帮助您实现多个属性的通知属性已更改 - WPF 通知属性已更改以获取属性

每次更改 DeviceCollection 时,你都会调用 DeviceCollectionChanged() 方法吗?如何设置设备集合?

您可以实现 ObservableCollection(本答案的底部),或者,根据您设置 DeviceCollection 的方式,例如,如果 DeviceCollection 来自列表,您可以实现如下内容:

private IEnumerable<IDeviceInformationVM> deviceCollection;
public IEnumerable<IDeviceInformationVM> DeviceCollection 
{
 get
  {
    return deviceCollection;
  }
  set
  {
    deviceCollection = value; 
    RaisePropertyChanged(() => DisconnectedDevices);
    RaisePropertyChanged(() => DeviceCollection);
  }
}
DeviceCollection = GetListOfIDeviceInformationVM(); //will automatically raise property changed and update your TextBlock

您不必继续打电话给看起来相当乏味的RaisePropertyChanged()

CollectionDevice 集合的类型更改为 ObservableCollection,然后引发事件 CollectionChanged 如下: DeviceCollection.CollectionChanged + = DeviceCollection_CollectionChanged ;我给你一个在 MVVM 中用一个类 RelayCommand 实现

此处视图 : (主视图)

<Window x:Class="WpfApplication.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:WpfApplication"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
    <local:MainViewModel/>
</Window.DataContext>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <TextBlock Text="{Binding DisconnectedDevices, Mode=TwoWay}" Height="25" Width="175" Grid.Row="0" />
    <Button Grid.Row="1" Content="Click" Command="{Binding ToggleExecuteCommand}"  Width="100" Height="25"/>
</Grid>

视图模型

(主视图模型)

    using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
namespace WpfApplication
{
    public class MainViewModel : INotifyPropertyChanged
    {
        private string disconnectedDevices;
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
        public MainViewModel()
        {
            ToggleExecuteCommand = new RelayCommand(ChangeCollection);
            DeviceCollection = new ObservableCollection<DeviceInformationVM>();
            DeviceCollection.CollectionChanged += DeviceCollection_CollectionChanged;
        }
        private void ChangeCollection(object obj)
        {
            DeviceCollection.Add(new DeviceInformationVM { MyProperty = "TEST" });
        }
        private void DeviceCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            NotifyCollectionChangedAction action = e.Action;
            if (action == NotifyCollectionChangedAction.Add)
            {
                DisconnectedDevices = "Somme thing added to collection";
            }
            if (action == NotifyCollectionChangedAction.Remove)
            {
                DisconnectedDevices = "Somme thing removed from collection";
            }
        }
        public string DisconnectedDevices
        {
            get { return this.disconnectedDevices; }
            set
            {
                if (value != this.disconnectedDevices)
                {
                    this.disconnectedDevices = value;
                    NotifyPropertyChanged("DisconnectedDevices");
                }
            }
        }
        public ObservableCollection<DeviceInformationVM> DeviceCollection { get; set; }
        public RelayCommand ToggleExecuteCommand { get; set; }
    }
}

中继命令:

using System;

使用System.Windows.Input;

命名空间 WPF 应用程序{ 公共类 中继命令 : ICommand { 私人操作执行;

    private Predicate<object> canExecute;
    private event EventHandler CanExecuteChangedInternal;
    public RelayCommand(Action<object> execute)
        : this(execute, DefaultCanExecute)
    {
    }
    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
        if (execute == null)
        {
            throw new ArgumentNullException("execute");
        }
        if (canExecute == null)
        {
            throw new ArgumentNullException("canExecute");
        }
        this.execute = execute;
        this.canExecute = canExecute;
    }
    public event EventHandler CanExecuteChanged
    {
        add
        {
            CommandManager.RequerySuggested += value;
            this.CanExecuteChangedInternal += value;
        }
        remove
        {
            CommandManager.RequerySuggested -= value;
            this.CanExecuteChangedInternal -= value;
        }
    }
    public bool CanExecute(object parameter)
    {
        return this.canExecute != null && this.canExecute(parameter);
    }
    public void Execute(object parameter)
    {
        this.execute(parameter);
    }
    public void OnCanExecuteChanged()
    {
        EventHandler handler = this.CanExecuteChangedInternal;
        if (handler != null)
        {
            handler.Invoke(this, EventArgs.Empty);
        }
    }
    public void Destroy()
    {
        this.canExecute = _ => false;
        this.execute = _ => { return; };
    }
    private static bool DefaultCanExecute(object parameter)
    {
        return true;
    }
}

}

和最终设备信息

    using System;
namespace WpfApplication
{
    public interface IDeviceInformationVM
    {
        string MyProperty { get; set; }
    }
    public class DeviceInformationVM : IDeviceInformationVM
    {
        public string MyProperty
        {
            get; set;
        }
    }
}

希望对你有帮助