【问题标题】:How to reset Background color to default in MVVM?如何在 MVVM 中将背景颜色重置为默认值?
【发布时间】:2020-02-17 21:22:47
【问题描述】:

我正在使用 MVVM 在 UWP 中创建登录页面。当输入的密码不正确时,我希望将 PasswordBox 的边框更改为红色以表示它不正确。

我将 SolidColorBrush 变量绑定到边框和背景。

        private SolidColorBrush _validationColorBorder;
        public SolidColorBrush ValidationColorBorder
        {
            get{ return _validationColorBorder; }
            set
            {
                _validationColorBorder = value;
                RaisePropertyChanged();
            }
        }

        private SolidColorBrush _validationColorBackground;
        public SolidColorBrush ValidationColorBackground
        {
            get { return _validationColorBackground; }
            set
            {
                _validationColorBackground = value;
                RaisePropertyChanged();
            }
        }

在 ViewModel 中,我使用以下方法将颜色设置为验证颜色:

            ValidationColorBackground = (SolidColorBrush)Application.Current.Resources["TextBoxBackgroundThemeBrush"];
            ValidationColorBorder = (SolidColorBrush)Application.Current.Resources["TextBoxBorderThemeBrush"];

我的问题是,在我将密码框背景和边框设置为这些颜色后,我希望之后能够将它们设置回默认颜色。

如何将颜色设置回应用程序的默认颜色?并且能够通过将我的 SolidColorBrush 变量设置为这些默认颜色以 MVVM 格式执行此操作吗?

感谢您的帮助!

【问题讨论】:

  • 与颜色有关;我认为这应该在 XAML 中完全处理。
  • @Stefan 我如何能够仅在 XAML 中处理验证并重置为默认颜色?或者,你的意思也是代码隐藏?
  • 嗯...颜色的重置可能是一个触发器。也许在焦点或类似事件上(仅限 XAML)。颜色,变为红色,可能是基于 ViewModel 中的一个布尔值,它表示授权失败。这样你的 ViewModel 就不会被颜色污染,更符合 MVVM 范式。
  • 好的,但 UWP 中不支持触发器。我需要做更多这样的事情吗? stackoverflow.com/questions/31929071/…
  • 嗯...是的,看起来像。我没有做过那么多 UWP,但它似乎是有效的。不过,您需要找到一个适用的“触发器”。好处是您可以仅从 ViewModel 中的单个属性定义所有颜色(以及其他内容,例如消息)。

标签: c# xaml mvvm uwp


【解决方案1】:

如何在 MVVM 中将背景颜色重置为默认值?

请查看PasswrodBox 样式。默认背景和边框颜色为TextControlBackgroundTextControlBorderBrush。 因此,您可以在设置自定义颜色之前获取它们。

defaultBgColor = (SolidColorBrush)Application.Current.Resources["TextControlBackground"];
defaultBorderColor = (SolidColorBrush)Application.Current.Resources["TextControlBorderBrush"];

如果你想回滚,你只需要将上面的值复制到你的自定义绑定属性中。更多内容请参考以下内容。

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private SolidColorBrush defaultBgColor;
    private SolidColorBrush defaultBorderColor;

    public ViewModel()
    {
        defaultBgColor = (SolidColorBrush)Application.Current.Resources["TextControlBackground"];
        defaultBorderColor = (SolidColorBrush)Application.Current.Resources["TextControlBorderBrush"];

        ValidationColorBackground = (SolidColorBrush)Application.Current.Resources["TextBoxBackgroundThemeBrush"];
        ValidationColorBorder = (SolidColorBrush)Application.Current.Resources["TextBoxBorderThemeBrush"];
    }
    private SolidColorBrush _validationColorBorder;
    public SolidColorBrush ValidationColorBorder
    {
        get { return _validationColorBorder; }
        set
        {
            _validationColorBorder = value;
            RaisePropertyChanged();
        }
    }

    private void RaisePropertyChanged([CallerMemberName] string propertyName = null)
    {
        this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private SolidColorBrush _validationColorBackground;
    public SolidColorBrush ValidationColorBackground
    {
        get { return _validationColorBackground; }
        set
        {
            _validationColorBackground = value;
            RaisePropertyChanged();
        }
    }

    public ICommand BtnClickCommand
    {
        get
        {
            return new RelayCommand(() =>
            {
                ValidationColorBackground = defaultBgColor;
                ValidationColorBorder = defaultBorderColor;
            });
        }
    }

}

【讨论】:

    【解决方案2】:

    您可以使用 Bevaviours 来完成此操作。你需要一个属性来绑定错误。

    您还需要创建一些样式

    查看示例(=> 取自 Prism)

    using Microsoft.Xaml.Interactivity;
    using Prism.Windows.Validation;
    using System.Collections.ObjectModel;
    using System.Linq;
    using Windows.UI.Xaml;
    
    namespace ams.TaskmanagerClient.Behaviors
    {
       Public Class HighlightFormFieldOnErrors : Behavior<FrameworkElement>
        {
            Public ReadOnlyCollection<String> PropertyErrors
            {
                Get { return (ReadOnlyCollection<String>)GetValue(PropertyErrorsProperty); }
                Set { SetValue(PropertyErrorsProperty, value); }
            }
    
            Public String HighlightStyleName
            {
                Get { return (String)GetValue(HighlightStyleNameProperty); }
                Set { SetValue(HighlightStyleNameProperty, value); }
            }
    
            Public String OriginalStyleName
            {
                Get { return (String)GetValue(OriginalStyleNameProperty); }
                Set { SetValue(OriginalStyleNameProperty, value); }
            }
    
            Public static DependencyProperty PropertyErrorsProperty =
                DependencyProperty.RegisterAttached("PropertyErrors", typeof(ReadOnlyCollection<String>), typeof(HighlightFormFieldOnErrors), New   r   opertyMetadata(BindableValidator.EmptyErrorsCollection, OnPropertyErrorsChanged));
    
            // The default For this Property only applies To TextBox controls. 
            Public static DependencyProperty HighlightStyleNameProperty =
                DependencyProperty.RegisterAttached("HighlightStyleName", typeof(String), typeof(HighlightFormFieldOnErrors), New   r op ert yMetadata("HighlightTextBoxStyle"));
    
            // The default For this Property only applies To TextBox controls. 
            protected static DependencyProperty OriginalStyleNameProperty =
                DependencyProperty.RegisterAttached("OriginalStyleName", typeof(Style), typeof(HighlightFormFieldOnErrors), New   r op ert yMetadata("BaseTextBoxStyle"));
    
            Private static void OnPropertyErrorsChanged(DependencyObject d, DependencyPropertyChangedEventArgs args)
            {
                If (args == Null || args.NewValue == Null)
                {
                    return;
                }
    
                var control = ((Behavior<FrameworkElement>)d).AssociatedObject;
                var propertyErrors = (ReadOnlyCollection<String>)args.NewValue;
    
                Style style = (propertyErrors.Any()) ?
                    (Style)Application.Current.Resources[((HighlightFormFieldOnErrors)d).HighlightStyleName] :
                    (Style)Application.Current.Resources[((HighlightFormFieldOnErrors)d).OriginalStyleName];
    
                control.Style = style;
            }
    
            protected override void OnAttached()
            {
                base.OnAttached();
            }
    
            protected override void OnDetaching()
            {
                base.OnDetaching();
            }
        }
    }
    
    
    <Page
        x:Class="ams.TaskmanagerClient.Views.SettingsPage"
        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:helper="using:ams.TaskmanagerClient.Helpers"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        Style="{StaticResource PageStyle}"
        xmlns:prismMvvm="using:Prism.Windows.Mvvm"
        xmlns:vm="using:ams.TaskmanagerClient.ViewModels"
        xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
        xmlns:i="using:Microsoft.Xaml.Interactivity"
        xmlns:ic="using:Microsoft.Xaml.Interactions.Core"
        xmlns:helpers="using:ams.TaskmanagerClient.Helpers"
        xmlns:behaviors="using:ams.TaskmanagerClient.Behaviors"      
        prismMvvm:ViewModelLocator.AutoWireViewModel="True" 
        xmlns:xaml="using:Windows.UI.Xaml"
        mc:Ignorable="d">
        <Page.Resources>
            <helper:EnumToBooleanConverter x:Key="EnumToBooleanConverter" EnumType="ElementTheme" />
        </Page.Resources>
    
        <Grid>
          <PasswordBox x:Name="ClientSecretPasswordBox" 
                       x:Uid="ClientSecretPasswordBox" 
                       AutomationProperties.AutomationId="ClientSecretPasswordBox" 
                       AutomationProperties.IsRequiredForForm="True" 
                       Password="{Binding NewClient.ClientSecret, Mode=TwoWay}"
                       IsTabStop="True">
              <i:Interaction.Behaviors>
                  <behaviors:HighlightFormFieldOnErrors OriginalStyleName="BasePasswordBoxStyle"
                                                        HighlightStyleName="HighlightPasswordBoxStyle"
                                                        PropertyErrors="{Binding NewClient.Errors[ClientSecret], Mode=OneWay}" />
              </i:Interaction.Behaviors>
          </PasswordBox>
        </Grid>
    </Page>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-26
      • 2016-05-24
      • 2012-05-21
      • 2022-07-05
      • 1970-01-01
      • 2013-01-06
      • 2022-10-18
      • 2011-10-09
      相关资源
      最近更新 更多