Как преобразовать логические && два видимости

У меня есть два отдельных конвертера для видимости: один зависит от того, было ли обновлено поле, а другой - от того, разрешено ли отображение поля. Я использую updateField один для каждого текстового элемента на моей странице, чтобы рядом с обновленным полем отображалась звездочка. Но некоторые текстовые элементы видны только некоторым пользователям в зависимости от уровней разрешений.

Например:

<Image Visibility="{Binding ElementName=MyObject, Path=UpdatedFields, Mode=OneWay, Converter={StaticResource updatedFieldConverter}, ConverterParameter=FieldToTest}" Source="Properties:Resources.star_yellow" />

и

<TextBlock FontSize="21" Foreground="{DynamicResource LabelBrush}" Text="{x:Static Properties:Resources.Some_Text}" Visibility="{Binding Source={StaticResource allowedFields}, Path=Some_Text_Field, Converter={StaticResource visibilityConverter}}" />

Моя проблема в том, что для полей, требующих разрешения, мне нужно запустить оба конвертера, чтобы определить, появляется ли звездочка. Есть ли способ сделать логическое «И» на результатах двух преобразователей?

Я просмотрел этот пост, но это не так. похоже, позволяет передавать разные наборы параметров двум разным конвертерам.

-------Обновлять--------

Я также попытался создать MultiValueConverter с этим xaml

<Image Grid.Row="4" Grid.Column="0" Source="star_yellow.png">
   <Image.Visibility>
      <MultiBinding Converter="{StaticResource combinedVisibilityConverter}" ConverterParameter="FieldToTest" >
         <Binding ElementName="allowedFieldsModel" Path="Some_Text_Field" Mode="OneWay" />                        
         <Binding ElementName="MyObject" Path="UpdatedFields" Mode="OneWay" />
      </MultiBinding>
   </Image.Visibility>
</Image>

Но когда он поступает в конвертер, оба значения - «DependencyProperty.UnsetValue». Так что я, видимо, здесь что-то делаю не так.

--------Решение---------

Мне пришлось изменить это, но потом это сработало.

<Image.Visibility>
    <MultiBinding Converter="{StaticResource combinedVisibilityConverter}" ConverterParameter="FieldToTest">
        <Binding Source="{StaticResource allowedFieldsModel}" Path="Some_Text_Field" />
        <Binding Path="MyObject.UpdatedFields" />
    </MultiBinding>
</Image.Visibility>

person Bill    schedule 28.06.2011    source источник


Ответы (4)


Вы можете использовать MultiBinding вместе с коротким, сделанным вручную IMultiValueConverter.

Пример:

<StackPanel>
    <StackPanel.Resources>
        <local:MultiBooleanToVisibilityConverter x:Key="Converter" />
    </StackPanel.Resources>
    <CheckBox x:Name="Box1" />
    <CheckBox x:Name="Box2" />
    <TextBlock Text="Hidden Text">
        <TextBlock.Visibility>
            <MultiBinding Converter="{StaticResource Converter}">
                <Binding ElementName="Box1"
                            Path="IsChecked" />
                <Binding ElementName="Box2"
                            Path="IsChecked" />
            </MultiBinding>
        </TextBlock.Visibility>
    </TextBlock>                   
</StackPanel>

... и преобразователь ...

class MultiBooleanToVisibilityConverter : IMultiValueConverter
{
    public object Convert(object[] values,
                            Type targetType,
                            object parameter,
                            System.Globalization.CultureInfo culture)
    {
        bool visible = true;
        foreach (object value in values)
            if (value is bool)
                visible = visible && (bool)value;

        if (visible)
            return System.Windows.Visibility.Visible;
        else
            return System.Windows.Visibility.Hidden;
    }

    public object[] ConvertBack(object value,
                                Type[] targetTypes,
                                object parameter,
                                System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
person Jens    schedule 28.06.2011
comment
@Psiclopz: Я привел пример. Это работает на МОЕЙ машине =) Ваш случай кажется более сложным, но, возможно, это помогает. - person Jens; 28.06.2011
comment
У меня это почти сработало, но, как вы сказали, мой случай был немного сложнее. Я разместил свое решение выше. Спасибо за вашу помощь. - person Bill; 29.06.2011

Поздно для вечеринки, но более простое решение - просто перенести элемент управления в другой элемент управления. Я предпочитаю это иметь много конвертеров, которые делают разные вещи.

<Border Visibility="{Binding Value1, Converter={convertersDF:Converter_ValueToVisibility}}">
 <ComboBox Visibility="{Binding Value2, Converter={convertersDF:Converter_ValueToVisibility}}"/>
</Border>
person Asheh    schedule 23.03.2015
comment
Блестяще! Не нужно писать дополнительный класс для такой простой вещи! - person TheBoyan; 20.05.2015
comment
Из чата WPF пришли к выводу, что границы - это самый дешевый способ сделать что-то подобное (вместо StackPanel). - person Lynn Crumbling; 04.06.2015
comment
Я пытался отредактировать это, чтобы помочь всем, но он был отклонен, потому что люди на этом сайте глупы - person Asheh; 08.06.2015

Одна вещь, которая пришла в голову, - это, возможно, вместо двух разных логических полей одно битовое поле, созданное с помощью операции ИЛИ вместе updatedField и allowedField. Тогда у вас может быть три преобразователя значений, работающих с одним и тем же полем.

Или просто вычислите другое поле в своей модели данных, которое выполняет там операцию AND. Вероятно, это более эффективно (с точки зрения времени выполнения).

person i_am_jorf    schedule 28.06.2011
comment
Вы можете подробнее рассказать об этом? Я не понимаю, как вы это сделаете в xaml. - person Bill; 28.06.2011
comment
Вы вообще этого не делаете в xaml. - person i_am_jorf; 28.06.2011

Вы можете передать преобразователю массив из двух объектов в ConverterParameter - построении массива в XAML.

person Kieren Johnstone    schedule 28.06.2011