编辑:我创建了一个示例项目,显示我已完成的工作和不工作的工作 . https://github.com/jmooney5115/clear-multibinding
我有一个带控件的WPF应用程序(文本框,数据网格等) . 当控件上的值发生变化时,我需要通过更改背景颜色来指示它 . 保存更改后,背景颜色需要返回到未更改状态而不重新加载控件 . 这个应用程序不是MVVM,不判断我继承了它 .
我有完美的代码,可以使用MultiBinding和值转换器来改变颜色 . 问题是我无法弄清楚如何在我的代码中调用Save()后重置后台 . 我已经尝试过DataContext = null然后DataContext = this但控件闪烁 . 一定有更好的方法 .
问:如何在不重新加载控件的情况下将背景重置为未更改状态?
MultiBinding XAML - 通过将字符串[]传递给BackgroundColorConverter来实现 . string [0]是OneTime绑定 . string 1是另一个绑定 .
<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();
}
}
Updates
编辑:这是数据网格单元的多重绑定 . 如果多重绑定转换器返回true,请将背景颜色设置为LightBlue . 如果为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();
}
}
}
Final Update
这个问题解答了如何在DataGridCell上使用MultiBinding:Update MultiBinding on DataGridCell
2 回答
IHMO MVVM解决方案(如Rekshino提出的)肯定比非MVVM解决方案更好 . 视图模型应该注意跟踪修改后的数据 .
无论如何,既然你继承了这个应用程序,你必须考虑转换整个代码所需的时间,有时候是不可能的 . 因此,在这种情况下,您可以在保存数据时强制每个单个多重绑定“刷新” .
我们假设这是你的XAML(有两个或更多
TextBoxes
):单击"Save"
Button
时,可以强制MultiBindings以这种方式更新自己的目标:您可以在this answer中找到
FindVisualChildren
实现 . 我希望它可以帮到你 .您必须将
bool Saved
属性粘贴到DeviceObj
并处理它,如果Name
或其他内容已更改 .ViewModel:
Converter:
XAML: