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

时间:2018-09-09 11:43:24

标签: c# wpf xaml

我想在WPF应用程序中更改文本框输入时更改主窗口颜色。当前,当鼠标悬停或进入文本框时,颜色会更改,但由于我不希望这种效果,因此我将其删除。但是我希望当鼠标光标进入文本框时具有相同的效果,它应该更改主要背景色。

MainWindow的背景色是:

  • 浅蓝色,当鼠标光标进入A输入框

  • 浅绿色,当鼠标光标进入B输入框

  • 浅灰色,其他所有情况。

Model.cs

def log_call(msg: str) -> Callable[[Callable[..., TypeT], ...], TypeT]:

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

BoolToBackgroundColorConverter

 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
    }

Xaml

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

2 个答案:

答案 0 :(得分:3)

我已经修改了您的源代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main3);


    preferenceConfig = new SharedPreferenceConfig(getApplicationContext());

    if (preferenceConfig.readLoginStatus()) {
        startActivity(new Intent(this, Main2Activity.class));
        finish();

    }


    Prof_Section = (LinearLayout) findViewById(R.id.prof_section);
    SignOut = (Button) findViewById(R.id.butn_logout);
    SignIn = (SignInButton) findViewById(R.id.butn_login);
    Name = (TextView) findViewById(R.id.name);
    Email = (TextView) findViewById(R.id.email);
    Prof_Pic = (ImageView) findViewById(R.id.prof_pic);
    SignIn.setOnClickListener(this);
    SignOut.setOnClickListener(this);
    Prof_Section.setVisibility(View.GONE);
    GoogleSignInOptions signInOptions = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).requestEmail().requestProfile().build();
    googleApiClient = new GoogleApiClient.Builder(this).enableAutoManage(this, this).addApi(Auth.GOOGLE_SIGN_IN_API, signInOptions).build();


}


@Override
public void onClick(View v) {

    switch (v.getId()) {
        case R.id.butn_login:
            signIn();
            break;

        case R.id.butn_logout:
            signOut();
            break;


    }

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}


private void signIn() {
    Intent intent = Auth.GoogleSignInApi.getSignInIntent(googleApiClient);
    startActivityForResult(intent, REQ_CODE);


}

private void signOut() {
    Auth.GoogleSignInApi.signOut(googleApiClient).setResultCallback(new ResultCallback<Status>() {
        @Override
        public void onResult(@NonNull Status status) {
            updateUI(false);
        }
    });

}


private void updateUI(boolean isLogin) {

    if (isLogin) {
        Prof_Section.setVisibility(View.VISIBLE);
        SignIn.setVisibility(View.GONE);


    } else {
        Prof_Section.setVisibility(View.GONE);
        SignIn.setVisibility(View.VISIBLE);

    }


}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == REQ_CODE) {
        GoogleSignInResult googleSignInResult = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
        GoogleSignInAccount account = googleSignInResult.getSignInAccount();


        String name = account.getDisplayName();
        String email = account.getEmail();
        String img_url = account.getPhotoUrl().toString();
        Name.setText(name);
        Email.setText(email);
        Glide.with(this).load(img_url).into(Prof_Pic);
        updateUI(true);
        preferenceConfig.writeLoginStatus(true);


        try {
            Intent sendData = new Intent(Main3Activity.this, Detail.class);

            name = account.getDisplayName();
            email = account.getEmail();


            img_url = account.getPhotoUrl().toString();
            sendData.putExtra("p_name", name);
            sendData.putExtra("p_email", email);
            sendData.putExtra("p_url", img_url);

            startActivity(sendData);

        } catch (Exception e) {
            Toast.makeText(Main3Activity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
        }


    } else {
        Toast.makeText(Main3Activity.this, "Login Failed", Toast.LENGTH_SHORT).show();
    }

}

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

请将System.Windows.Interactivity dll添加到项目中,并创建继承ICommand接口的RelayCommand类。

答案 1 :(得分:1)

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

这是更新的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>

您的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
    }
}