简体   繁体   English

WPF应用程序中文本框输入更改时如何更改主窗口颜色?

[英]How to change main window color when textbox input changes in WPF application?

I want to change main window color when textbox input changes in WPF application. 我想在WPF应用程序中更改文本框输入时更改主窗口的颜色。 Currently, when mouse hover or enters the textbox color changes but I will remove this as I do not want this effect. 当前,当鼠标悬停或进入文本框时,颜色会更改,但由于我不希望这种效果,因此我将其删除。 But I want the same effect when mouse cursor enters into textboxes, it should change main back ground colors. 但是我希望当鼠标光标进入文本框时具有相同的效果,它应该更改主要背景色。

MainWindow background color is: MainWindow背景颜色为:

  • LightBlue, when mouse cursor enters A inputbox 浅蓝色,当鼠标光标进入A输入框时

  • LightGreen, when mouse cursor enters B inputbox 浅绿色,当鼠标光标进入B输入框时

  • LightGray,all other cases. 浅灰色,其他所有情况。

Model.cs Model.cs

public abstract class ObservableBase : INotifyPropertyChanged
{
    public void Set<TValue>(ref TValue field, TValue newValue, [CallerMemberName] string propertyName = "")
    {
        if (!EqualityComparer<TValue>.Default.Equals(field, default(TValue)) && field.Equals(newValue)) return;
        field = newValue;
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}


public abstract class ViewModelBase : ObservableBase
{
    public bool IsInDesignMode
        => (bool)DesignerProperties.IsInDesignModeProperty
            .GetMetadata(typeof(DependencyObject))
            .DefaultValue;
}

MainViewModel.cs MainViewModel.cs

 public class MainViewModel : ViewModelBase
    {
        public MainViewModel()
        {
            valueAisValid = true;
            valueBisValid = true;
            if (IsInDesignMode)
            {
                Calc();
            }
        }

        #region Properties

        private string valueA;
        public string ValueA
        {
            get => valueA;
            set
            {
                if (!string.IsNullOrEmpty(value))
                {
                    Set(ref valueA, value);
                    Set(ref valueAisValid, double.TryParse(ValueA, out double d));
                    NotifyPropertyChanged(nameof(ValueAIsValid));
                    Calc();
                }
            }
        }

        private bool valueAisValid;
        public bool ValueAIsValid => valueAisValid;

        private string valueB;
        public string ValueB
        {
            get => valueB;
            set
            {
                if (!string.IsNullOrEmpty(value))
                {
                    Set(ref valueB, value);
                    Set(ref valueBisValid, double.TryParse(ValueB, out double d));
                    NotifyPropertyChanged(nameof(ValueBIsValid));
                    Calc();
                }
            }
        }

        private bool valueBisValid;
        public bool ValueBIsValid => valueBisValid;

        private string valueC;
        public string ValueC
        {
            get => valueC;
            set => Set(ref valueC, value);
        }

        private string valueD;
        public string ValueD
        {
            get => valueD;
            set => Set(ref valueD, value);
        }

        public bool InputsValid => ValueAIsValid && ValueBIsValid;

        #endregion

        #region Methods

        private void Calc()
        {
            if (InputsValid)
            {
                double sum = Convert.ToDouble(valueA) + Convert.ToDouble(valueB);
                double product = Convert.ToDouble(valueA) * Convert.ToDouble(valueB);
                ValueC = sum.ToString(CultureInfo.InvariantCulture);
                ValueD = product.ToString(CultureInfo.InvariantCulture);
            }
            else
            {
                ValueC = "NAN";
                ValueD = "NAN";
            }
        }

        #endregion
    }

BoolToBackgroundColorConverter BoolToBackgroundColorConverter

   public class BoolToBackgroundColorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value != null && !(bool)value)
            {
                return new SolidColorBrush(Colors.Red);
            }
            else if (value != null && (bool)value && parameter != null)
            {
                return (SolidColorBrush)parameter;
            }
            else
            {
                return new SolidColorBrush(Colors.White);
            }
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

Xaml XAML

<Window x:Class="WPFTestApplication.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:WPFTestApplication.ViewModel"
        xmlns:local1="clr-namespace:WPFTestApplication"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>
    <Window.Resources>
        <local1:BoolToBackgroundColorConverter x:Key="BoolToBackgroundColorConverter"/>
    </Window.Resources>

    <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.Resources>
            <SolidColorBrush x:Key="LightGreen" Color="LightGreen" />
            <SolidColorBrush x:Key="LightBlue" Color="LightBlue" />
            <SolidColorBrush x:Key="white" Color="white" />
            <Style TargetType="TextBlock">
                <Setter Property="VerticalAlignment" Value="Center"/>
            </Style>
            <Style TargetType="TextBox" x:Key="TextBox">
                <Setter Property="VerticalContentAlignment" Value="Center"/>
                <Setter Property="Margin" Value="10"/>
                <Setter Property="Width" Value="100"/>
                <Setter Property="Height" Value="25"/>
                <Setter Property="Grid.Column" Value="1"/>
            </Style>
            <Style TargetType="TextBox" x:Key="TextBoxA" BasedOn="{StaticResource TextBox}">
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="{Binding ValueAIsValid, Converter={StaticResource BoolToBackgroundColorConverter}, ConverterParameter={StaticResource LightBlue}}" />
                    </Trigger>
                </Style.Triggers>
                <Setter Property="Background" Value="{Binding ValueAIsValid, Converter={StaticResource BoolToBackgroundColorConverter}, ConverterParameter={StaticResource white}}" />
            </Style>
            <Style TargetType="TextBox" x:Key="TextBoxB" BasedOn="{StaticResource TextBox}">
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="{Binding ValueBIsValid, Converter={StaticResource BoolToBackgroundColorConverter}, ConverterParameter={StaticResource LightGreen}}" />
                    </Trigger>
                </Style.Triggers>
                <Setter Property="Background" Value="{Binding ValueBIsValid, Converter={StaticResource BoolToBackgroundColorConverter}, ConverterParameter={StaticResource white}}" />
            </Style>
            <Style TargetType="TextBox" BasedOn="{StaticResource TextBox}"/>
        </Grid.Resources>

        <TextBlock Text="Value A"/>
        <TextBox Text="{Binding ValueA, UpdateSourceTrigger=PropertyChanged}"

                 Style="{StaticResource TextBoxA}"/>

        <TextBlock Text="Value B" Grid.Row="1"/>
        <TextBox Text="{Binding ValueB, UpdateSourceTrigger=PropertyChanged}"

                 Style="{StaticResource TextBoxB}"

                 Grid.Row="1"/>

        <TextBlock Text="Value C" Grid.Row="2"/>
        <TextBox Text="{Binding ValueC}"


                 IsReadOnly="True"

                 Grid.Row="2"/>

        <TextBlock Text="Value D" Grid.Row="3"/>
        <TextBox Text="{Binding ValueD}"

                 IsReadOnly="True"

                 Grid.Row="3"/>


    </Grid>
</Window>

I have modified your source code: 我已经修改了您的源代码:

<Window x:Class="WpfApplication1.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:WpfApplication1"
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

<Window.DataContext>
    <local:MainViewModel/>
</Window.DataContext>
<Window.Resources>
    <local:BoolToBackgroundColorConverter x:Key="BoolToBackgroundColorConverter"/>
</Window.Resources>

<Grid Background="{Binding BackgroundColor}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
    <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.Resources>
            <SolidColorBrush x:Key="LightGreen" Color="LightGreen" />
            <SolidColorBrush x:Key="LightBlue" Color="LightBlue" />
            <SolidColorBrush x:Key="LightGray" Color="LightGray" />
            <SolidColorBrush x:Key="White" Color="White" />
            <Style TargetType="TextBlock">
                <Setter Property="VerticalAlignment" Value="Center"/>
            </Style>
            <Style TargetType="TextBox">
                <Setter Property="VerticalContentAlignment" Value="Center"/>
                <Setter Property="Margin" Value="10"/>
                <Setter Property="Width" Value="100"/>
                <Setter Property="Height" Value="25"/>
                <Setter Property="Grid.Column" Value="1"/>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                    </Trigger>
                </Style.Triggers>
                <!--<Setter Property="Background" Value="{StaticResource White}" />-->
            </Style>                
        </Grid.Resources>

        <TextBlock Text="Value A"/>
        <TextBox Text="{Binding ValueA, UpdateSourceTrigger=PropertyChanged}">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseEnter" >
                    <i:InvokeCommandAction Command="{Binding MouseEnterCommand}" CommandParameter="{StaticResource LightBlue}" />
                </i:EventTrigger>
                <i:EventTrigger EventName="MouseLeave" >
                    <i:InvokeCommandAction Command="{Binding MouseLeaveCommand}" CommandParameter="{StaticResource White}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </TextBox>

        <TextBlock Text="Value B" Grid.Row="1"/>
        <TextBox Text="{Binding ValueB, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseEnter" >
                    <i:InvokeCommandAction Command="{Binding MouseEnterCommand}" CommandParameter="{StaticResource LightGreen}" />
                </i:EventTrigger>
                <i:EventTrigger EventName="MouseLeave" >
                    <i:InvokeCommandAction Command="{Binding MouseLeaveCommand}" CommandParameter="{StaticResource White}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </TextBox>

        <TextBlock Text="Value C" Grid.Row="2"/>
        <TextBox Text="{Binding ValueC}"                 Grid.Row="2">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseEnter" >
                    <i:InvokeCommandAction Command="{Binding MouseEnterCommand}" CommandParameter="{StaticResource LightGray}" />
                </i:EventTrigger>
                <i:EventTrigger EventName="MouseLeave" >
                    <i:InvokeCommandAction Command="{Binding MouseLeaveCommand}" CommandParameter="{StaticResource White}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </TextBox>

        <TextBlock Text="Value D" Grid.Row="3"/>
        <TextBox Text="{Binding ValueD}"                 Grid.Row="3">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseEnter" >
                    <i:InvokeCommandAction Command="{Binding MouseEnterCommand}" CommandParameter="{StaticResource LightGray}" />
                </i:EventTrigger>
                <i:EventTrigger EventName="MouseLeave" >
                    <i:InvokeCommandAction Command="{Binding MouseLeaveCommand}" CommandParameter="{StaticResource White}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </TextBox>

    </Grid>
</Grid>

public class MainViewModel : ViewModelBase
    {
        public ICommand MouseEnterCommand { get; set; }
        public ICommand MouseLeaveCommand { get; set; }
        public MainViewModel()
        {
            valueAisValid = true;
            valueBisValid = true;
            MouseEnterCommand = new RelayCommand<object>(MouseEnterCommandHandler);
            MouseLeaveCommand =new  RelayCommand<object>(MouseLeaveCommandHandler);
            if (IsInDesignMode)
            {
                Calc();
            }
        }

        #region Properties

        private string _backgroundColor;
        public string BackgroundColor
        {
            get { return _backgroundColor; }
            set { _backgroundColor = value; NotifyPropertyChanged(nameof(BackgroundColor)); }
        }


        private string valueA;
        public string ValueA
        {
            get { return valueA; }
            set
            {
                if (!string.IsNullOrEmpty(value))
                {
                    double d;
                    Set(ref valueA, value);
                    Set(ref valueAisValid, double.TryParse(ValueA, out d));
                    NotifyPropertyChanged(nameof(ValueAIsValid));
                    Calc();
                }
            }
        }

        private bool valueAisValid;
        public bool ValueAIsValid => valueAisValid;

        private string valueB;
        public string ValueB
        {
            get { return valueB; }
            set
            {
                if (!string.IsNullOrEmpty(value))
                {
                    double d;
                    Set(ref valueB, value);
                    Set(ref valueBisValid, double.TryParse(ValueB, out d));
                    NotifyPropertyChanged(nameof(ValueBIsValid));
                    Calc();
                }
            }
        }

        private bool valueBisValid;
        public bool ValueBIsValid => valueBisValid;

        private string valueC;
        public string ValueC
        {
            get { return valueC; }
            set { Set(ref valueC, value); }
        }

        private string valueD;
        public string ValueD
        {
            get { return valueD; }
            set { Set(ref valueD, value); }
        }

        public bool InputsValid => ValueAIsValid && ValueBIsValid;

        #endregion

        #region Methods

        private void Calc()
        {
            if (InputsValid)
            {
                double sum = Convert.ToDouble(valueA) + Convert.ToDouble(valueB);
                double product = Convert.ToDouble(valueA) * Convert.ToDouble(valueB);
                ValueC = sum.ToString(CultureInfo.InvariantCulture);
                ValueD = product.ToString(CultureInfo.InvariantCulture);
            }
            else
            {
                ValueC = "NAN";
                ValueD = "NAN";
            }
        }

        private void MouseEnterCommandHandler(object parameter)
        {
            if (parameter != null)
            {
                BackgroundColor = parameter.ToString();
            }
        }

        private void MouseLeaveCommandHandler(object parameter)
        {
            if (parameter !=null)
            {
                BackgroundColor = parameter.ToString();
            }
        }

        #endregion
    }

Please add System.Windows.Interactivity dll to the project and Create a RelayCommand class inheriting ICommand interface. 请将System.Windows.Interactivity dll添加到项目中,并创建继承ICommand接口的RelayCommand类。

Here's the MainWindow.xaml.cs 这是MainWindow.xaml.cs

using System.Windows;
using System.Windows.Input;
using System.Windows.Media;

namespace WpfApp1
{
    public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();
            AttachCustomBehaviors();
        }

        // There's a better way of doing this, read attached behavior in wpf
        private void AttachCustomBehaviors()
        {
            TextBoxA.GotFocus += (s, args) => ChangeMainWindowBackground(this, Brushes.LightBlue);
            TextBoxB.GotFocus += (s, args) => ChangeMainWindowBackground(this, Brushes.LightGreen);
            TextBoxA.LostFocus += (s, args) => ChangeMainWindowBackground(this, Brushes.Gray);
            TextBoxB.LostFocus += (s, args) => ChangeMainWindowBackground(this, Brushes.Gray);
        }

        private void InputFieldsHovered(object sender, MouseEventArgs e)
        {
            if (!TextBoxA.IsFocused && !TextBoxB.IsFocused)
            {
                ChangeMainWindowBackground(this, Brushes.Gray);
            }
            else if(TextBoxA.IsFocused)
            {
                ChangeMainWindowBackground(this, Brushes.LightBlue);
            }
            else if (TextBoxB.IsFocused)
            {
                ChangeMainWindowBackground(this, Brushes.LightGreen);
            }
        }

        private static void ChangeMainWindowBackground(Window window, SolidColorBrush color)
        {
            window.Background = color;
        }
    }
}

Here's the updated xaml: 这是更新的xaml:

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"
        Background="Gray">
    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>

    <Window.Resources>
        <local:BoolToBackgroundColorConverter x:Key="BoolToBackgroundColorConverter"/>
    </Window.Resources>

    <Grid x:Name="MainGrid" HorizontalAlignment="Center" VerticalAlignment="Center">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.Resources>
            <SolidColorBrush x:Key="White" Color="White" />
            <Style TargetType="TextBlock">
                <Setter Property="VerticalAlignment" Value="Center"/>
            </Style>
            <Style TargetType="TextBox" x:Key="TextBox">
                <Setter Property="VerticalContentAlignment" Value="Center"/>
                <Setter Property="Margin" Value="10"/>
                <Setter Property="Width" Value="100"/>
                <Setter Property="Height" Value="25"/>
                <Setter Property="Grid.Column" Value="1"/>
            </Style>
            <Style TargetType="TextBox" x:Key="TextBoxA" BasedOn="{StaticResource TextBox}">
                <Setter Property="Background" Value="{Binding ValueAIsValid, Converter={StaticResource BoolToBackgroundColorConverter}, ConverterParameter={StaticResource White}}" />
            </Style>
            <Style TargetType="TextBox" x:Key="TextBoxB" BasedOn="{StaticResource TextBox}">
                <Setter Property="Background" Value="{Binding ValueBIsValid, Converter={StaticResource BoolToBackgroundColorConverter}, ConverterParameter={StaticResource White}}" />
            </Style>
            <Style TargetType="TextBox" BasedOn="{StaticResource TextBox}"/>
        </Grid.Resources>

        <TextBlock Text="Value A"/>
        <TextBox x:Name="TextBoxA" Text="{Binding ValueA, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource TextBoxA}" MouseEnter="InputFieldsHovered"/>

        <TextBlock Text="Value B" Grid.Row="1"/>
        <TextBox x:Name="TextBoxB" Text="{Binding ValueB, UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource TextBoxB}" Grid.Row="1" MouseEnter="InputFieldsHovered"/>

        <TextBlock Text="Value C" Grid.Row="2"/>
        <TextBox x:Name="TextBoxC" Text="{Binding ValueC}" IsReadOnly="True" Background="Gray" Grid.Row="2" MouseEnter="InputFieldsHovered"/>

        <TextBlock Text="Value D" Grid.Row="3"/>
        <TextBox x:Name="TextBoxD" Text="{Binding ValueD}" Background="Gray" IsReadOnly="True" Grid.Row="3" MouseEnter="InputFieldsHovered"/>
    </Grid>
</Window>

Your ViewModel.cs 您的ViewModel.cs

using System;
using System.Globalization;

namespace WpfApp1
{
    public class MainViewModel : ViewModelBase
    {
        public MainViewModel()
        {
            valueAisValid = true;
            valueBisValid = true;
        }

        #region Properties

        private string valueA;
        public string ValueA
        {
            get => valueA;
            set
            {
                Set(ref valueA, value);
                Set(ref valueAisValid, double.TryParse(ValueA, out double d));
                NotifyPropertyChanged(nameof(ValueAIsValid));
                Calc();
            }
        }

        private bool valueAisValid;
        public bool ValueAIsValid => valueAisValid;

        private string valueB;
        public string ValueB
        {
            get => valueB;
            set
            {
                Set(ref valueB, value);
                Set(ref valueBisValid, double.TryParse(ValueB, out double d));
                NotifyPropertyChanged(nameof(ValueBIsValid));
                Calc();
            }
        }

        private bool valueBisValid;
        public bool ValueBIsValid => valueBisValid;

        private string valueC;
        public string ValueC
        {
            get => valueC;
            set => Set(ref valueC, value);
        }

        private string valueD;
        public string ValueD
        {
            get => valueD;
            set => Set(ref valueD, value);
        }

        public bool InputsValid => ValueAIsValid && ValueBIsValid;

        #endregion

        #region Methods

        private void Calc()
        {
            if (InputsValid)
            {
                double sum = Convert.ToDouble(valueA) + Convert.ToDouble(valueB);
                double product = Convert.ToDouble(valueA) * Convert.ToDouble(valueB);
                ValueC = sum.ToString(CultureInfo.InvariantCulture);
                ValueD = product.ToString(CultureInfo.InvariantCulture);
            }
            else
            {
                ValueC = "NAN";
                ValueD = "NAN";
            }
        }

        #endregion
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM