更新 DataGridCell 上的 MultiBinding
Update MultiBinding on DataGridCell
我正在通过 MultiBinding
和 IMultiValueConverter
在应用程序中集成 属性 变化检测。因此,当用户对 'DataGrid'、DataGridCell' changes background color. My issue is that when the user saves their work I cannot remove the changed background without a screen flicker. I can do
DataContext = nullthen
DataContext = this` 进行更改时,它会导致屏幕闪烁。我无法调用更新绑定将 MultiBinding 重置为默认值。
问:如何更新 DataGridCell 上的 MultiBinding,如下所示?
不幸的是,这不是 MVVM。我创建了一个显示问题的项目:https://github.com/jmooney5115/clear-multibinding
此解决方案适用于 TextBox 但不适用于 DataGridCell:
foreach (TextBox textBox in FindVisualChildren<TextBox>(this))
{
multiBindingExpression = BindingOperations.GetMultiBindingExpression(textBox, TextBox.BackgroundProperty);
multiBindingExpression.UpdateTarget();
}
这是数据网格单元格的多重绑定。多值转换器采用原始值和修改后的值。如果更改值,则 returns true 将背景颜色设置为浅蓝色。如果为 false,则背景为默认颜色。
<DataGrid.Columns>
<DataGridTextColumn Header="Destination Tag name" Binding="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
<!-- -->
<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>
///
///
/// Property changed and display it on a datagrid.
///
/// Boolean Converter
/// </summary>
public class BackgroundColorConverterBool : IMultiValueConverter
{
/// <summary>
///
/// </summary>
/// <param name="values"></param>
/// <param name="targetType"></param>
/// <param name="parameter"></param>
/// <param name="culture"></param>
/// <returns>True is property has changed</returns>
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values[0] is null || values[1] is null) return false;
if (values.Length == 2)
if (values[0].Equals(values[1]))
return false;
else
return true;
else
return true;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
更新
使用标记为我的答案的解决方案,我能够对其进行扩展以概括 UpdateState() 方法。
foreach (var prop in this.GetType().GetProperties())
_memo[prop.Name] = prop.GetValue(this);
我不会依赖一次性绑定模式和清除绑定的技巧来跟踪数据的变化。改为实现类似 Memento 模式的东西。
添加此代码以在项目 class 中存储状态:
private Dictionary<string, object> _memo = new Dictionary<string, object>();
public object this[string key]
{
get
{
object o;
_memo.TryGetValue(key, out o);
return o;
}
}
public void UpdateState()
{
_memo["Name"] = Name;
_memo["Description"] = Description;
_memo["Alias"] = Alias;
_memo["Value"] = Value;
OnPropertyChanged("Item[]");
}
要使索引器 this[]
工作,您必须重命名 class(例如 ItemVm
),因为 class 名称和成员名称不能相同, .NET 使用 "Item"
作为索引器 属性 名称。
请注意,索引器的通知具有 "Item[]"
格式,并且 VerifyProperty()
方法也应修复:
private void VerifyProperty(string propertyName)
{
if (propertyName == null || propertyName == "Item[]")
return;
现在,要在 window 中使用未修改的值,请像这样绑定到索引器:
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource BackgroundColorConverterBool}">
<Binding Path="Value" />
<Binding Path="[Value]" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="LightBlue"/>
</DataTrigger>
</Style.Triggers>
</Style>
创建项目时保存初始状态:
for(var i = 0; i < 100; i++)
{
Items.Add(new ItemVm
{
Alias = string.Format("Item {0}", i.ToString()),
Description = string.Format("Description {0}", i.ToString()),
Name = string.Format("Name {0}", i.ToString()),
Value = string.Format("Value {0}", i.ToString())
});
Items[i].UpdateState();
}
并在单击按钮时保存状态更改:
private void Button_Click(object sender, RoutedEventArgs e)
{
UIHelper.UpdateDataBindings<Control>(this);
foreach(var item in Items)
{
item.UpdateState();
}
}
我正在通过 MultiBinding
和 IMultiValueConverter
在应用程序中集成 属性 变化检测。因此,当用户对 'DataGrid'、DataGridCell' changes background color. My issue is that when the user saves their work I cannot remove the changed background without a screen flicker. I can do
DataContext = nullthen
DataContext = this` 进行更改时,它会导致屏幕闪烁。我无法调用更新绑定将 MultiBinding 重置为默认值。
问:如何更新 DataGridCell 上的 MultiBinding,如下所示?
不幸的是,这不是 MVVM。我创建了一个显示问题的项目:https://github.com/jmooney5115/clear-multibinding
此解决方案适用于 TextBox 但不适用于 DataGridCell:
foreach (TextBox textBox in FindVisualChildren<TextBox>(this))
{
multiBindingExpression = BindingOperations.GetMultiBindingExpression(textBox, TextBox.BackgroundProperty);
multiBindingExpression.UpdateTarget();
}
这是数据网格单元格的多重绑定。多值转换器采用原始值和修改后的值。如果更改值,则 returns true 将背景颜色设置为浅蓝色。如果为 false,则背景为默认颜色。
<DataGrid.Columns>
<DataGridTextColumn Header="Destination Tag name" Binding="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
<!-- -->
<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>
///
///
/// Property changed and display it on a datagrid.
///
/// Boolean Converter
/// </summary>
public class BackgroundColorConverterBool : IMultiValueConverter
{
/// <summary>
///
/// </summary>
/// <param name="values"></param>
/// <param name="targetType"></param>
/// <param name="parameter"></param>
/// <param name="culture"></param>
/// <returns>True is property has changed</returns>
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values[0] is null || values[1] is null) return false;
if (values.Length == 2)
if (values[0].Equals(values[1]))
return false;
else
return true;
else
return true;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
更新
使用标记为我的答案的解决方案,我能够对其进行扩展以概括 UpdateState() 方法。
foreach (var prop in this.GetType().GetProperties())
_memo[prop.Name] = prop.GetValue(this);
我不会依赖一次性绑定模式和清除绑定的技巧来跟踪数据的变化。改为实现类似 Memento 模式的东西。
添加此代码以在项目 class 中存储状态:
private Dictionary<string, object> _memo = new Dictionary<string, object>();
public object this[string key]
{
get
{
object o;
_memo.TryGetValue(key, out o);
return o;
}
}
public void UpdateState()
{
_memo["Name"] = Name;
_memo["Description"] = Description;
_memo["Alias"] = Alias;
_memo["Value"] = Value;
OnPropertyChanged("Item[]");
}
要使索引器 this[]
工作,您必须重命名 class(例如 ItemVm
),因为 class 名称和成员名称不能相同, .NET 使用 "Item"
作为索引器 属性 名称。
请注意,索引器的通知具有 "Item[]"
格式,并且 VerifyProperty()
方法也应修复:
private void VerifyProperty(string propertyName)
{
if (propertyName == null || propertyName == "Item[]")
return;
现在,要在 window 中使用未修改的值,请像这样绑定到索引器:
<Style TargetType="{x:Type DataGridCell}">
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource BackgroundColorConverterBool}">
<Binding Path="Value" />
<Binding Path="[Value]" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Background" Value="LightBlue"/>
</DataTrigger>
</Style.Triggers>
</Style>
创建项目时保存初始状态:
for(var i = 0; i < 100; i++)
{
Items.Add(new ItemVm
{
Alias = string.Format("Item {0}", i.ToString()),
Description = string.Format("Description {0}", i.ToString()),
Name = string.Format("Name {0}", i.ToString()),
Value = string.Format("Value {0}", i.ToString())
});
Items[i].UpdateState();
}
并在单击按钮时保存状态更改:
private void Button_Click(object sender, RoutedEventArgs e)
{
UIHelper.UpdateDataBindings<Control>(this);
foreach(var item in Items)
{
item.UpdateState();
}
}