WPF / XAML - сравните «SelectedIndex» двух комбинированных списков (DataTrigger?) - PullRequest
1 голос
/ 01 октября 2009

У меня есть два комбинированных списка с одинаковым содержанием. пользователь не должен иметь права выбирать один и тот же элемент дважды. поэтому содержимое выпадающих списков (= selectedindex?) никогда не должно быть равным.

моей первой попыткой было сопоставить выбранный индекс с устройством сбора данных, чтобы показать / скрыть кнопку:

<DataTrigger Binding="{Binding ElementName=comboBox1, Path=SelectedIndex}" Value="{Binding ElementName=comboBox2, Path=SelectedIndex}">
     <Setter Property="Visibility" Value="Hidden" />
</DataTrigger>

кажется, что невозможно использовать Value = {Binding}. Есть ли другой способ (если это возможно без использования конвертера)? заранее спасибо!

Ответы [ 2 ]

3 голосов
/ 02 октября 2009

Вариант 1

Вы можете использовать ValidationRules - это также может быть сделано в XAML и будет работать для одноразовой ситуации. Это было бы чрезвычайно локализовано, и я бы не рекомендовал это, так как правило не подлежало бы повторному использованию. Может быть, кто-то еще может придумать общее правило, чтобы охватить различные входные данные. Попробуйте это.

<ComboBox>
    <ComboBox.SelectedValue>
        <Binding Path="Whatever" UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <local:ComparisonValidationRule />
            </Binding.ValidationRules>
        </Binding>
    </ComboBox.SelectedValue>
</ComboBox>

И, возможно, ComparisonRule выглядит следующим образом, и это правило должно быть в коде для этого правила, чтобы видеть элементы управления в визуальном дереве.

public class ComparisonValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
        if (this.firstComboBox.SelectedIndex == this.secondComboBox.SelectedIndex)
            return new ValidationResult(false, "These two comboboxes must supply different values.");
        else return new ValidationResult(true, null);
    }
}

ИЛИ вы можете определенно сделать это с помощью триггера, если хотите установить некоторые интересные вещи вне шаблона ошибки.

Вариант 2

Используйте триггер и конвертер. Это действительно не так уж сложно. Вот как бы я это сделал.

<Style x:Key="{x:Type ComboBox}" TargetType="{x:Type ComboBox}">
    <Style.Triggers>
        <DataTrigger Value="True">
            <DataTrigger.Binding>
                <MultiBinding Converter="{StaticResource EqualsConverter}">
                    <Binding ElementName="cbOne" Path="SelectedIndex"/>
                    <Binding ElementName="cbTwo" Path="SelectedIndex"/>
                </MultiBinding>
            </DataTrigger.Binding>
            <Setter Property="Background" Value="Yellow"/>
        </DataTrigger>
    </Style.Triggers>
</Style>

и конвертер в коде позади

public class EqualsConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType,
                          object parameter, CultureInfo culture)
    {
        if (values[0] is int && values[1] is int && values[0] == values[1])
            return true;
        return false;
    }

    public object[] ConvertBack(object value, Type[] targetTypes,
                                object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}
0 голосов
/ 24 февраля 2010

Если ComboBox совместно используют один и тот же источник элементов, установите флаг для базового объекта данных, когда элемент выбирается через первый ComboBox.

В табличке данных для объекта данных, отображаемого во втором поле со списком, напишите источник данных, который связывается с этим свойством и делает что-то подходящее.

Убедитесь, что вы используете TwoWay для первого ComboBox.

...