【问题标题】:C#:How to change button icon in MVVM?C#:如何更改 MVVM 中的按钮图标?
【发布时间】:2018-01-15 09:57:44
【问题描述】:

我尝试将Button 图标更改为Click_Event,所以目前我有这样的xaml:

<Button Content="{materialDesign:PackIcon LanDisconnect}" Command="{Binding Connect}" />

在 ViewModel 中:

public ICommand Connect
{
    get
    {
        _Connect = new RelayCommand(
            param => ConnectChip());
        return _Connect;
    }
}

我应该如何将命令Connect中的按钮图标更改为{MaterialDesign:PackIcon LanConnect}?谢谢!

【问题讨论】:

  • 您应该查看 MaterialDesignInXamlToolkit 的 MainDemo.Wpf 项目中的 Buttons.xaml
  • 在 get 之外分配您的 _Connect 字段,或者在分配新的 RelayCommand 之前检查它是否为空。每次调用 get 时,您的代码都会创建一个新命令
  • 我认为这不是最好的方法。应该使用命令来执行诸如保存或取消之类的操作。 UI 元素外观的更改应通过控件模板完成,在您的情况下,可能是事件触发器。
  • 视图模型属性上应该有一个或多个 DataTriggers,由命令更改。根据该属性的值,DataTriggers 会将按钮内容设置为不同的值。

标签: c# wpf button mvvm


【解决方案1】:

虽然一些 cmets 提出了更高级的解决方案(例如使用 DataTriggers)。我建议(至少从一开始)您只需要为按钮内容添加绑定。然后您可以向视图模型添加一个属性并通过命令对其进行更新。

在您的情况下,您使用的是 Material Design 内容。

因此,在您的视图模型中,您可能希望包含一个图标属性:

using MaterialDesignThemes.Wpf;

public PackIconKind IconKind
{
    get { return _IconKind; }
    set { SetField(ref _IconKind, value); }
}
private PackIconKind _IconKind = PackIconKind.LanDisconnect;

See this reference for the SetField method

然后将您的按钮 XAML 更改为:

<Button Command="{Binding MyCommand}" Width="100" Height="32">
    <materialDesign:PackIcon Kind="{Binding IconKind}" />
</Button>

这将为按钮中的图标设置绑定。现在视图模型可以随时更改Kind。我更喜欢在构造函数中设置命令。我首先有一个命令属性如下:

public ICommand MyCommand { get; }

在构造函数中:

MyCommand = new RelayCommand(UpdateIcon);

然后将 UpdateIcon 方法添加到视图模型中。然后可以从其他地方调用此方法(不仅仅是按钮命令)。

protected void UpdateIcon()
{
    IconKind = MaterialDesignThemes.Wpf.PackIconKind.LanConnect;
}

【讨论】:

    【解决方案2】:

    您可以将ButtonContent 属性绑定到您在ConnectChip() 方法中设置为新值的PackIcon 属性。

    XAML:

    <Button Content="{Binding Icon}" Command="{Binding Connect}" />
    

    查看模型:

    public class ViewModel : INotifyPropertyChanged
    {
        private ICommand _Connect;
        public ICommand Connect
        {
            get
            {
                _Connect = new RelayCommand(
                    param => ConnectChip());
                return _Connect;
            }
        }
    
        private PackIcon _icon = new PackIcon { Kind = PackIconKind.LanDisconnect };
        public PackIcon Icon
        {
            get { return _icon; }
            set { _icon = value; NotifyPropertyChanged(); }
        }
    
        private void ConnectChip()
        {
            //change icon:
            Icon = new PackIcon { Kind = PackIconKind.Airballoon };
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

    【讨论】:

    • 虽然这是一个合理的答案,但最好绑定到 PackIcon Kind 属性(如我的回答中所示),这将允许稍后使用其他内容(例如文本)更轻松地扩展按钮.
    • 您的意思是根据我的编辑答案?原来的包含一个 Uri 属性。
    • 这不是真的
    • 哪一部分不正确?
    • 不用担心 :) 两个答案总比没有好。
    猜你喜欢
    • 1970-01-01
    • 2020-06-13
    • 2014-05-07
    • 1970-01-01
    • 2019-10-23
    • 1970-01-01
    • 2019-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多