我想在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();
}
}
答案 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
}
}