【问题标题】:A simple way in WPF MVVM to reuse property method?WPF MVVM中重用属性方法的简单方法?
【发布时间】:2015-09-13 12:19:25
【问题描述】:

我是 WPF MVVM 的新手。这是我的视图模型正在做的事情:

按下按钮并启动 ping 命令以查看服务器是否可用:

- 如果为 true,则按钮设置为隐藏。

- 如果为 false,则带有消息(“Servers not availables”)的标签设置为 可见

如何重用以下 IsVisible 方法来设置 Label 的可见性?

using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Input;

namespace WpfTest
{
    public class PrnViewModel1 : ViewModelBase
    {
        private ICommand m_PrnServPingCommand;
        private Visibility _isVisible=Visibility.Visible;


        public PrnViewModel1()
        {
            PrnServPingCommand = new RelayCommand(new Action<object>(PrnServPing));
        }

        public ICommand PrnServPingCommand
        {
            get
            {
                return m_PrnServPingCommand;
            }
            set
            {
                m_PrnServPingCommand = value;
            }
        }

        public void PrnServPing(object obj)
        {
            string[] serverNames = { "svmsimp1", "svmsimp2" };
            bool serversArePingable = Cmethods.PingableAll(serverNames);
            if (serversArePingable)
            {
                IsVisible = Visibility.Hidden; //Button is Hidden
            }
            else
            {
                //*** Label with Message "Servers not pingable" set to visible
            }
        }

        public Visibility IsVisible
        {
            get
            {
                return _isVisible;
            }
            set
            {
                _isVisible = value;
                OnPropertyChanged("IsVisible");
            }
        }
    }
}

【问题讨论】:

    标签: c# wpf mvvm visibility reusability


    【解决方案1】:

    您可以使用IValueConverter 来反转标签上的Visibility

    这是一个示例实现:

    public static class Extensions
    {
        public static System.Windows.Visibility Reversed(this System.Windows.Visibility visibility)
        {
            if (visibility == System.Windows.Visibility.Visible)
                visibility = System.Windows.Visibility.Collapsed;
            else if (visibility == System.Windows.Visibility.Collapsed || visibility == System.Windows.Visibility.Hidden)
                visibility = System.Windows.Visibility.Visible;
    
            return visibility;
        }
    }
    
    public class VisibilityReversedConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return ((System.Windows.Visibility)value).Reversed();
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return ((System.Windows.Visibility)value).Reversed();
        }
    }
    

    用法:

    <TextBlock Text="Servers not available" Visibility="{Binding Visibility, Converter={StaticResource VisibilityReversedConverter}}" ... />
    

    不要忘记在Resources实例化转换器。有关转换器的教程,请参阅 here

    【讨论】:

      【解决方案2】:

      我自己经常在 ViewModel 中使用Visibility 类型(避免编写转换器来控制布局,因为Hidden != Collapsed)。

      您需要的是 2 个属性来控制标签和按钮的可见性或单个属性 (bool) 来切换显示哪个和转换器(带有反转参数或仅 2 个转换器)。

      这是使用转换器和参数的解决方案(奖励 - MarkupExtension!):

      public class SuperConverter : MarkupExtension, IValueConverter
      {
          public SuperConverter() { }
      
          public override object ProvideValue(IServiceProvider serviceProvider)
          {
              return this;
          }
      
          public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
          {
              if (value is bool)
              {
                  bool inverted = false;
                  if (parameter != null && parameter.ToString().Contains("Inverted"))
                      inverted = true;
                  return (inverted && (bool)value || !inverted && !((bool)value)) ? Visibility.Hidden : Visibility.Visible;
              }
              throw new InvalidCastException();
          }
      
          public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
          {
              throw new NotImplementedException();
          }
      }
      

      并使用它(您必须在 ViewModel 中有 bool IsOperationInProgress,该值将切换文本或按钮的显示):

      <TextBlock Visibility="{Binding IsOperationInProgress, Converter={l:SuperConverter}}" ... />
      <Button Visibility="{Binding IsOperationInProgress, Converter={l:SuperConverter}, ConverterParameter=Inverted}" ... />
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-07
        • 2021-11-08
        • 2023-03-31
        相关资源
        最近更新 更多