Как изменить фоновый цвет, используя связывание при определенных условиях - PullRequest
2 голосов
/ 11 марта 2011

Мне нужно изменить цвет фона решетки данных, если в модели представления установлен определенный флаг.Если флаг имеет значение false, оставьте его в покое.

Есть ли что-то вроде "условного связывания", которое могло бы помочь в этом сценарии.

Ответы [ 4 ]

3 голосов
/ 11 марта 2011

Вы можете выполнить привязку через 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.

1 голос
/ 12 марта 2011

Это общее требование для преобразования логического значения в один из двух экземпляров произвольного типа.

Лично я считаю, что это лучший инструмент для работы: Универсальный преобразователь Bool To Value (но в этом мнении может быть некоторая погрешность)

Поместите экземпляр предоставленного конвертера в ресурсы вашего UserControl: -

 <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"]);
    }     

Это установит привязку для каждой строки при загрузке.

1 голос
/ 12 марта 2011

Да, подход к решению этой проблемы с использованием IValueConverter правильный, и я часто им пользуюсь. Но в вашем случае я предлагаю использовать только декларативный подход , поскольку дополнительные конвертеры являются дополнительной абстракцией в вашем решении, и чтобы понять эту логику, другой программист должен пропустить 2 файла: декларативную и конверторную реализацию. И цвета, которые будут переключаться, идентифицируются в конвертере :(, но не в декларативной части. Чтобы избежать этого, используйте Microsoft.Expression.Interactions и System.Windows.Interactivity из Blend SDK. Пример кода:

    < 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) TriggerAction код:

[ContentProperty ( "Binding")]

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>

0 голосов
/ 11 марта 2011

Вы можете решить эту проблему, используя DataTriggers , изменив стиль, когда ваша привязка является определенным условием.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...