【发布时间】:2011-03-11 20:42:00
【问题描述】:
如果视图模型中的特定标志为真,我需要更改数据网格的背景颜色。如果标志为假,则不要理会它。
在这种情况下是否有类似“条件绑定”的东西。
【问题讨论】:
标签: silverlight binding
如果视图模型中的特定标志为真,我需要更改数据网格的背景颜色。如果标志为假,则不要理会它。
在这种情况下是否有类似“条件绑定”的东西。
【问题讨论】:
标签: silverlight binding
您可以通过 ValueConverter 进行绑定:
.... BackgroundColor="{Binding BooleanFlag, Converter=BoolToColorConverter}" ....
MSDN 有更多信息,但您的转换器将类似于以下伪代码:
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
if (value is boolean)
{
return (value as boolean) ? Color.Red : Color.Blue;
}
}
您不需要实现 ConvertBack 方法,因为它是单向绑定。
当BooleanFlag 更改时,您需要引发属性更改事件。
【讨论】:
DataGridRow 实例,以便它对每一行的每个DataContext 都敏感?
将布尔值转换为某种任意类型的两个实例之一的常见要求。
我个人认为这是完成这项工作的最佳工具:Generic Bool To Value Converter(但这种观点可能存在一些偏见)
将提供的转换器的实例放在您的用户控件的资源中:-
<UserControl.Resources>
<local:BoolToBrushConverter x:Key="Highlighter" FalseValue="White" TrueValue="Yellow" />
</UserControl.Resources>
现在您可以将此转换器应用于绑定,将 ViewModel 中的布尔值绑定到 Brush 类型的属性。
但是您有一个更大的问题,您如何将此转换器应用于单个数据行? DataGrid 不允许您直接设置在每一行上设置的绑定。
假设您不是“视图中没有代码”,您可以使用另一个静态资源来保存一个简单的Binding,然后使用数据网格LoadingRow 事件将其应用于加载的每一行.
<UserControl.Resources>
<local:BoolToBrushConverter x:Key="Highlighter" FalseValue="White" TrueValue="Yellow" />
<Binding x:Key="RowBackgroundBinding" Path="yourBoolProperty" Converter="{StaticResource Highlighter}" />
</UserControl.Resources>
在数据网格上:-
<DataGrid x:Name="dg" LoadingRow="dg_LoadingRow" ...>
然后在代码隐藏中:-
private void dg_LoadingRow(object sender, DataGridRowEventArgs e)
{
e.Row.SetBinding(DataGridRow.BackgroundProperty, (Binding)Resources["RowBackgroundBinding"]);
}
这将在每行加载时设置绑定。
【讨论】:
是的,使用 IValueConverter 解决这个问题的方法是正确的,我经常使用它。 但在您的情况下,我建议仅使用 声明性方法,因为额外的转换器是您解决方案中的额外抽象,并且要理解此逻辑,其他程序员必须忽略 2 个文件:声明性和转换器实现。并且将切换的颜色在转换器中标识:(但不在声明部分中。 为避免这种情况,请使用 Blend SDK 中的 Microsoft.Expression.Interactions 和 System.Windows.Interactivity。 示例代码:
< i:Interaction.Triggers>
< c:DataTrigger Binding="{Binding BooleanFlagFromViewModel}" Comparison="Equal" Value="True">
< c:ChangePropertyAction TargetName="LayoutRoot" PropertyName="Background" Value="#345678" />
< /c:DataTrigger>
< /i:Interaction.Triggers>
< /Grid>
希望对您有所帮助!祝你好运!
更新
当我在给 AnthonyWJones 的评论中写到避免通过 Key 访问绑定资源时,我建议使用 TriggerAction。
1) 触发动作代码:
[ContentProperty("绑定")]
public class ApplyBindingToDataGridRowAction : TriggerAction<DataGrid> { protected override void Invoke(object parameter) { DataGridRowEventArgs e = (DataGridRowEventArgs) parameter; e.Row.SetBinding(DataGridRow.BackgroundProperty, Binding); } public Binding Binding { get; set; } }
2) 在 XAML 中使用:
< i:EventTrigger EventName="LoadingRow"> < a:ApplyBindingToDataGridRowAction> < Binding Path="Is" Converter="{StaticResource Highlighter}"/> < /a:ApplyBindingToDataGridRowAction> < /i:EventTrigger> < /i:Interaction.Triggers>
【讨论】:
你可以使用DataTriggers解决这个问题,当你的绑定是特定条件时改变样式。
【讨论】: