C# 属性改变时的多重绑定颜色改变-如何实用地清除?
编辑:我创建了一个示例项目,其中显示了我所做的和不起作用的内容 我有一个带有控件(文本框、数据网格等)的WPF应用程序。当控件上的值更改时,我需要通过更改背景颜色来指示它。保存更改后,背景颜色需要返回到未更改的状态,而无需重新加载控件。这个应用程序不是MVVM,不要判断我继承了它 我有使用多重绑定和值转换器更改颜色的完美代码。问题是,在代码中调用Save()后,我无法确定如何重置背景。我尝试过使用DataContext=null,然后使用DataContext=this,但是控件会闪烁。一定有更好的办法 问:如何在不重新加载控件的情况下将背景重置为未更改的状态 MultiBinding XAML-它通过将字符串[]传递给BackgroundColorConverter来工作。字符串[0]是一次性绑定。字符串是另一个绑定C# 属性改变时的多重绑定颜色改变-如何实用地清除?,c#,.net,database,wpf,multibinding,C#,.net,Database,Wpf,Multibinding,编辑:我创建了一个示例项目,其中显示了我所做的和不起作用的内容 我有一个带有控件(文本框、数据网格等)的WPF应用程序。当控件上的值更改时,我需要通过更改背景颜色来指示它。保存更改后,背景颜色需要返回到未更改的状态,而无需重新加载控件。这个应用程序不是MVVM,不要判断我继承了它 我有使用多重绑定和值转换器更改颜色的完美代码。问题是,在代码中调用Save()后,我无法确定如何重置背景。我尝试过使用DataContext=null,然后使用DataContext=this,但是控件会闪烁。一定有更
<TextBox.Background>
<MultiBinding Converter="{StaticResource BackgroundColorConverter}">
<Binding Path="DeviceObj.Name" />
<Binding Path="DeviceObj.Name" Mode="OneTime" />
</MultiBinding>
</TextBox.Background>
BackgroundColorConverter.cs
/// <summary>
/// https://stackoverflow.com/questions/1224144/change-background-color-for-wpf-textbox-in-changed-state
///
/// Property changed
/// </summary>
public class BackgroundColorConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var colorRed = (System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#FFB0E0E6");
var colorWhite = (System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("White");
var unchanged = new SolidColorBrush(colorWhite);
var changed = new SolidColorBrush(colorRed);
if (values.Length == 2)
if (values[0].Equals(values[1]))
return unchanged;
else
return changed;
else
return changed;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
//
/// https://stackoverflow.com/questions/1224144/change-background-color-for-wpf-textbox-in-changed-state
///
///财产变更
///
公共类BackgroundColorConverter:IMultiValueConverter
{
公共对象转换(对象[]值,类型targetType,对象参数,CultureInfo区域性)
{
var colorRed=(System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString(“#ffb0e6”);
var colorWhite=(System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString(“白色”);
var unchanged=新的SolidColorBrush(colorWhite);
var changed=新的SolidColorBrush(彩色红色);
如果(values.Length==2)
如果(值[0]。等于(值[1]))
回报不变;
其他的
回报发生变化;
其他的
回报发生变化;
}
公共对象[]转换回(对象值,类型[]目标类型,对象参数,CultureInfo区域性)
{
抛出新的NotImplementedException();
}
}
更新
编辑:这是数据网格单元的多重绑定。如果多绑定转换器返回true,请将背景颜色设置为浅蓝色。如果为false,则背景为默认颜色
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
<!-- https://stackoverflow.com/questions/5902351/issue-while-mixing-multibinding-converter-and-trigger-in-style -->
<DataGridTextColumn.CellStyle>
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource BackgroundColorConverterBool}">
<Binding Path="Name" />
<Binding Path="Name" Mode="OneTime" />
</MultiBinding>
</DataTrigger.Binding>
</DataTrigger>
<Setter Property="Background" Value="LightBlue"></Setter>
</Style.Triggers>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
.
.
.
</DataGrid.Columns>
.
.
.
我使用此方法在保存后重置对象的绑定
/// <summary>
/// Update the data binding after a save to clear the blue that could be there when
/// a change is detected.
/// </summary>
/// <typeparam name="T">Type to search for</typeparam>
/// <param name="parentDepObj">Parent object we want to reset the binding for their children.</param>
public static void UpdateDataBinding<T>(DependencyObject parentDepObj) where T : DependencyObject
{
if (parentDepObj != null)
{
MultiBindingExpression multiBindingExpression;
foreach (var control in UIHelper.FindVisualChildren<T>(parentDepObj))
{
multiBindingExpression = BindingOperations.GetMultiBindingExpression(control, Control.BackgroundProperty);
if (multiBindingExpression != null)
multiBindingExpression.UpdateTarget();
}
}
}
//
///保存后更新数据绑定,以清除保存时可能出现的蓝色
///检测到更改。
///
///键入要搜索的内容
///父对象我们要为其子对象重置绑定。
公共静态void UpdateDataBinding(DependencyObject ParentDepbj),其中T:DependencyObject
{
if(parentDepObj!=null)
{
多绑定表达式多绑定表达式;
foreach(UIHelper.FindVisualChildren(parentDepObj)中的var控制)
{
multiBindingExpression=BindingOperations.GetMultiBindingExpression(control,control.BackgroundProperty);
if(multiBindingExpression!=null)
multiBindingExpression.UpdateTarget();
}
}
}
最终更新
这个问题回答了如何在DataGridCell上使用多重绑定:如果
名称
或其他内容已更改,则必须将bool Saved
属性粘贴到设备bj
并进行处理
视图模型:
public class Device : INotifyPropertyChanged
{
public string Name
{
get
{
return _name;
}
set
{
if (value != _name)
{
_name = value;
Saved = false;
NotifyPropertyChanged(nameof(Name));
}
}
}
private string _name;
public bool Saved
{
get
{
return _saved;
}
set
{
if (value != _saved)
{
_saved = value;
NotifyPropertyChanged(nameof(Saved));
}
}
}
private bool _saved = true;
public void Save()
{
//Saving..
Saved = true;
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string info)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info));
}
}
public class BoolToSolColBrushConverter : IValueConverter
{
private static SolidColorBrush changedBr = new SolidColorBrush(Colors.Red);
private static SolidColorBrush unchangedBr = new SolidColorBrush(Colors.Green);
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
try
{
if ((bool)value)
{
return unchangedBr;
}
}
catch (Exception)
{
}
return changedBr;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
<TextBox Text="{Binding Name}" Background="{Binding Saved, Converter={StaticResiurce BoolToSolColBrushConverter}}" />
转换器:
public class Device : INotifyPropertyChanged
{
public string Name
{
get
{
return _name;
}
set
{
if (value != _name)
{
_name = value;
Saved = false;
NotifyPropertyChanged(nameof(Name));
}
}
}
private string _name;
public bool Saved
{
get
{
return _saved;
}
set
{
if (value != _saved)
{
_saved = value;
NotifyPropertyChanged(nameof(Saved));
}
}
}
private bool _saved = true;
public void Save()
{
//Saving..
Saved = true;
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string info)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info));
}
}
public class BoolToSolColBrushConverter : IValueConverter
{
private static SolidColorBrush changedBr = new SolidColorBrush(Colors.Red);
private static SolidColorBrush unchangedBr = new SolidColorBrush(Colors.Green);
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
try
{
if ((bool)value)
{
return unchangedBr;
}
}
catch (Exception)
{
}
return changedBr;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
<TextBox Text="{Binding Name}" Background="{Binding Saved, Converter={StaticResiurce BoolToSolColBrushConverter}}" />
XAML:
public class Device : INotifyPropertyChanged
{
public string Name
{
get
{
return _name;
}
set
{
if (value != _name)
{
_name = value;
Saved = false;
NotifyPropertyChanged(nameof(Name));
}
}
}
private string _name;
public bool Saved
{
get
{
return _saved;
}
set
{
if (value != _saved)
{
_saved = value;
NotifyPropertyChanged(nameof(Saved));
}
}
}
private bool _saved = true;
public void Save()
{
//Saving..
Saved = true;
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string info)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info));
}
}
public class BoolToSolColBrushConverter : IValueConverter
{
private static SolidColorBrush changedBr = new SolidColorBrush(Colors.Red);
private static SolidColorBrush unchangedBr = new SolidColorBrush(Colors.Green);
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
try
{
if ((bool)value)
{
return unchangedBr;
}
}
catch (Exception)
{
}
return changedBr;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
<TextBox Text="{Binding Name}" Background="{Binding Saved, Converter={StaticResiurce BoolToSolColBrushConverter}}" />
如果
名称
或其他内容发生更改,则必须将bool Saved
属性粘贴到设备bj
并进行处理
视图模型:
public class Device : INotifyPropertyChanged
{
public string Name
{
get
{
return _name;
}
set
{
if (value != _name)
{
_name = value;
Saved = false;
NotifyPropertyChanged(nameof(Name));
}
}
}
private string _name;
public bool Saved
{
get
{
return _saved;
}
set
{
if (value != _saved)
{
_saved = value;
NotifyPropertyChanged(nameof(Saved));
}
}
}
private bool _saved = true;
public void Save()
{
//Saving..
Saved = true;
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string info)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info));
}
}
public class BoolToSolColBrushConverter : IValueConverter
{
private static SolidColorBrush changedBr = new SolidColorBrush(Colors.Red);
private static SolidColorBrush unchangedBr = new SolidColorBrush(Colors.Green);
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
try
{
if ((bool)value)
{
return unchangedBr;
}
}
catch (Exception)
{
}
return changedBr;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
<TextBox Text="{Binding Name}" Background="{Binding Saved, Converter={StaticResiurce BoolToSolColBrushConverter}}" />
转换器:
public class Device : INotifyPropertyChanged
{
public string Name
{
get
{
return _name;
}
set
{
if (value != _name)
{
_name = value;
Saved = false;
NotifyPropertyChanged(nameof(Name));
}
}
}
private string _name;
public bool Saved
{
get
{
return _saved;
}
set
{
if (value != _saved)
{
_saved = value;
NotifyPropertyChanged(nameof(Saved));
}
}
}
private bool _saved = true;
public void Save()
{
//Saving..
Saved = true;
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string info)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info));
}
}
public class BoolToSolColBrushConverter : IValueConverter
{
private static SolidColorBrush changedBr = new SolidColorBrush(Colors.Red);
private static SolidColorBrush unchangedBr = new SolidColorBrush(Colors.Green);
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
try
{
if ((bool)value)
{
return unchangedBr;
}
}
catch (Exception)
{
}
return changedBr;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
<TextBox Text="{Binding Name}" Background="{Binding Saved, Converter={StaticResiurce BoolToSolColBrushConverter}}" />
XAML:
public class Device : INotifyPropertyChanged
{
public string Name
{
get
{
return _name;
}
set
{
if (value != _name)
{
_name = value;
Saved = false;
NotifyPropertyChanged(nameof(Name));
}
}
}
private string _name;
public bool Saved
{
get
{
return _saved;
}
set
{
if (value != _saved)
{
_saved = value;
NotifyPropertyChanged(nameof(Saved));
}
}
}
private bool _saved = true;
public void Save()
{
//Saving..
Saved = true;
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string info)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info));
}
}
public class BoolToSolColBrushConverter : IValueConverter
{
private static SolidColorBrush changedBr = new SolidColorBrush(Colors.Red);
private static SolidColorBrush unchangedBr = new SolidColorBrush(Colors.Green);
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
try
{
if ((bool)value)
{
return unchangedBr;
}
}
catch (Exception)
{
}
return changedBr;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
<TextBox Text="{Binding Name}" Background="{Binding Saved, Converter={StaticResiurce BoolToSolColBrushConverter}}" />
IHMO MVVM解决方案(如建议的)肯定比非MVVM解决方案好。视图模型应该注意跟踪修改的数据
无论如何,既然你继承了这个应用程序,你必须考虑你需要多少时间来转换整个代码,有时是不可能的。因此,在这种情况下,您可以在保存数据时强制每个多重绑定“刷新”
假设这是您的XAML(带有两个或多个文本框
):
您可以在中找到FindVisualChildren
实现。我希望它能帮助您。IHMO MVVM解决方案(如建议的)肯定比非MVVM解决方案好。视图模型应该注意跟踪修改的数据
无论如何,既然你继承了这个应用程序,你必须考虑你需要多少时间来转换整个代码,有时是不可能的。因此,在这种情况下,您可以在保存数据时强制每个多重绑定“刷新”
假设这是您的XAML(带有两个或多个文本框
):
您可以在中找到
FindVisualChildren
实现。我希望它能帮助您。您可以通过为DeviceObj.Name
源属性引发PropertyChanged
事件来调用转换器。您是在寻找MVVM解决方案,还是不关心它?@mm8 PropertyChanged正在调用它,以将其更改为我的“修改”颜色。保存后我需要将其更改回。以前修改过的状态将变为当前未修改的状态。@IlVic我很想将其更改为MVVM,但.xaml.cs文件中的代码太多,这是该程序的一大不足。您可以调用您的转换程序