programing

여러 바인딩을 사용하여 C# WPF가 네이블입니까?

yellowcard 2023. 4. 15. 08:40
반응형

여러 바인딩을 사용하여 C# WPF가 네이블입니까?

GUI 섹션을 설명하는 WPF xaml 파일이 있는데 특정 컨트롤의 활성화/비활성화는 다른 두 가지 항목에 의존해야 합니다.현재 코드는 다음과 같습니다.

<ComboBox Name="MyComboBox"
          IsEnabled="{Binding ElementName=SomeCheckBox, Path=IsChecked}"/>

그러나 다음과 같은 다른 체크박스에 의존해야 합니다.

<ComboBox Name="MyComboBox"
          IsEnabled="{Binding ElementName=SomeCheckBox&AnotherCheckbox, Path=IsChecked}"/>

어떻게 하면 좋을까요?뭔가 명백한 걸 놓쳤거나 잘못된 방향으로 가고 있다고 느끼지 않을 수 없어요

를 구현하는 컨버터와 함께 사용할 수 있습니다.

답변을 드리면 복사하여 붙여넣을 수 있습니다.

필요한 정적 리소스:

<converterNamespace:BooleanAndConverter x:Key="booleanAndConverter" />

콤보 박스:

<ComboBox Name="MyComboBox">
  <ComboBox.IsEnabled>
    <MultiBinding Converter="{StaticResource booleanAndConverter}">
      <Binding ElementName="SomeCheckBox" Path="IsChecked" />
      <Binding ElementName="AnotherCheckbox" Path="IsChecked"  />
    </MultiBinding>
  </ComboBox.IsEnabled>
</ComboBox>

컨버터 코드:

namespace ConverterNamespace
{
    public class BooleanAndConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            foreach (object value in values)
            {
                if ((value is bool) && (bool)value == false)
                {
                    return false;
                }
            }
            return true;
        }
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotSupportedException("BooleanAndConverter is a OneWay converter.");
        }
    }
}

같은 버전의 단축판도 시험해 볼 수 있습니다.

public class BooleanAndConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return values.OfType<IConvertible>().All(System.Convert.ToBoolean);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

public class BooleanOrConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return values.OfType<IConvertible>().Any(System.Convert.ToBoolean);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

물론 가시성을 위해 컨버터가 필요할 수도 있습니다.

public class BooleanOrToVisibilityConverter : IMultiValueConverter
{
    public Visibility HiddenVisibility { get; set; }

    public bool IsInverted { get; set; }

    public BooleanOrToVisibilityConverter()
    {
        HiddenVisibility = Visibility.Collapsed;
        IsInverted = false;
    }

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        bool flag = values.OfType<IConvertible>().Any(System.Convert.ToBoolean);
        if (IsInverted) flag = !flag;
        return flag ? Visibility.Visible : HiddenVisibility;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

public class BooleanAndToVisibilityConverter : IMultiValueConverter
{
    public Visibility HiddenVisibility { get; set; }

    public bool IsInverted { get; set; }

    public BooleanAndToVisibilityConverter()
    {
        HiddenVisibility = Visibility.Collapsed;
        IsInverted = false;
    }

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        bool flag = values.OfType<IConvertible>().All(System.Convert.ToBoolean);
        if (IsInverted) flag = !flag;
        return flag ? Visibility.Visible : HiddenVisibility;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

MultiValueConverter와 함께 MultiBinding을 사용해야 할 것 같습니다.여기를 참조해 주세요.http://www.developingfor.net/wpf/multibinding-in-wpf.html

다음은 직접적인 관련 예를 제시하겠습니다.http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/5b9cd042-cacb-4aaa-9e17-2d615c44ee22

qqbenq의 답변에 대한 확장:

기능을 추가해당기능을추가했습니다.Count예를 들어, 의 일부 항목을 체크하고 싶은 경우ListView가 선택되었습니다.

컨버터:

public class IsEnabledConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        foreach (var value in values)
        {
            switch (value)
            {
                case bool b when !b:
                case int i when i == 0:
                    return false;
            }
        }

        return true;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        return null;
    }
}

네임스페이스 <theNamespace:IsEnabledConverter x:Key="IsEnabledConverter"/>

단추

<Button x:Name="MyButton">
    <Button.IsEnabled>
        <MultiBinding Converter="{StaticResource IsEnabledConverter}">
            <Binding ElementName="MyListView" Path="SelectedItems.Count"/>
            <Binding ElementName="MyCheckBox" Path="IsChecked"/>
        </MultiBinding>
    </Button.IsEnabled>
</Button>

다중 바인딩을 사용하지 않을 경우

public class AndEnabledTextBox : TextBox
{
    public static readonly DependencyProperty AndEnabled1SubProperty =
        DependencyProperty.Register(nameof(AndEnabled1), typeof(bool), typeof(AndEnabledTextBox), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnAndEnabledPropertyChanged)));
    public static readonly DependencyProperty AndEnabled2SubProperty =
        DependencyProperty.Register(nameof(AndEnabled2), typeof(bool), typeof(AndEnabledTextBox), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnAndEnabledPropertyChanged)));
    public bool AndEnabled1 { get { return (bool)GetValue(AndEnabled1SubProperty); } set { SetValue(AndEnabled1SubProperty, value); } }
    public bool AndEnabled2 { get { return (bool)GetValue(AndEnabled2SubProperty); } set { SetValue(AndEnabled2SubProperty, value); } }
    protected override void OnInitialized(EventArgs e)
    {
        base.OnInitialized(e);
        IsEnabled = AndEnabled1 && AndEnabled2;
    }
    protected static void OnAndEnabledPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        AndEnabledTextBox textBox = (AndEnabledTextBox)obj;
        textBox.IsEnabled = textBox.AndEnabled1 && textBox.AndEnabled2;
    }
}

상속된 컨트롤을 사용하면 XMAL이 더 단순해집니다.

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApp1">
    <StackPanel>
        <ToggleButton x:Name="switch1" Content="{Binding ElementName=switch1, Path=IsChecked}"/>
        <ToggleButton x:Name="switch2" Content="{Binding ElementName=switch2, Path=IsChecked}"/>
        <local:AndEnabledTextBox Text="TEXT"
                                 AndEnabled1="{Binding ElementName=switch1, Path=IsChecked, Mode=OneWay}"
                                 AndEnabled2="{Binding ElementName=switch2, Path=IsChecked, Mode=OneWay}"/>
    </StackPanel>
</Window>

언급URL : https://stackoverflow.com/questions/945427/c-sharp-wpf-isenabled-using-multiple-bindings

반응형