XAML - 更新不同属性更新

时间:2016-02-24 10:03:29

标签: c# wpf xaml

所以我有以下XAML:

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

视图模型具有以下属性:

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

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

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

我希望在DeviceCollection更改时更新TextBlock中的值。我知道我可以在DisconnectedDevices上调用RaisePropertyChanged,但我想知道是否可以在不同的属性更改事件上更新TextBlock。

全部谢谢!

编辑:感谢您使用ObservableCollection而不是IEnumerable的建议,遗憾的是,我不能随意更改集合类型。

每当集合发生变化时都会调用DeviceCollectionChanged方法(我知道这很乏味......)

进一步编辑:

已经开始了
RaisePropertyChanged(() => DisconnectedDevices);

我理解在问题中可能没有提供足够的信息来获得我想要做的事情,为此道歉

3 个答案:

答案 0 :(得分:0)

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

是的,你可以提出

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

请参阅此问题,它可能会帮助您实现多个属性的NotifyPropertyChanged- WPF Notify PropertyChanged for a Get Property

答案 1 :(得分:0)

每次更改DeviceCollection时是否调用DeviceCollectionChanged()方法?你如何设置DeviceCollection?

您可以实现ObservableCollection(this答案的底部),或者,根据您设置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()这看起来很乏味

答案 2 :(得分:0)

将CollectionDevice集合的类型更改为ObservableCollection,然后按如下方式引发事件CollectionChanged: DeviceCollection.CollectionChanged + = DeviceCollection_CollectionChanged; 我在MVVM中使用类RelayCommand

给你一个实现

这里是视图:( MainView)

<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>

ViewModel(主ViewModel)

    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; }

    }
}

RelayCommand:

using System;

使用System.Windows.Input;

命名空间WpfApplication {     公共类RelayCommand: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;
    }
}

}

最终DeviceInformation

    using System;

namespace WpfApplication
{
    public interface IDeviceInformationVM
    {
        string MyProperty { get; set; }
    }

    public class DeviceInformationVM : IDeviceInformationVM
    {
        public string MyProperty
        {
            get; set;
        }
    }
}

希望有所帮助