1

Wordアドイン用に、オフィスのタスクペインでホストされているユーザーコントロールがあります。

TextBox が値を持つまで WPF Button を非アクティブにする DataTrigger への回答と、ボタンの可視性を 2 つのテキストボックスのコンテンツにバインドする Cleanest way への回答に従って、正確に 2 つのテキストボックスに null 以外のコンテンツがある場合にボタンを有効にしようとしました。 .

コンバーター:

using System.Windows.Data;
using System.Globalization;

namespace RetrofitDocumentTool.Converter
{
    [ValueConversion(typeof(String), typeof(Boolean))]
    class StringToBooleanConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string val = (string)value;
            bool result = !string.IsNullOrEmpty(val);
            return result;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException("This converter is oneway only.");
        }
    }
}

XAML:

<UserControl
    ...>

    <UserControl.Resources>
        <Style x:Key="ErrorLabel" TargetType="Label">
            ...
        </Style>

        <Style x:Key="StandardLabel" TargetType="Label">
            ...
        </Style>

        <Style TargetType="TextBox">
            ...
        </Style>

        <conv:StringToBooleanConverter x:Key="StringToBoolean"/>
    </UserControl.Resources>

    <DockPanel LastChildFill="True">
        <Border CornerRadius="8">
            <Grid
                ...
                ...
                ...

                <TextBox
                    Name="Serial_Number"
                    ...>
                </TextBox>
                <TextBox
                    Name="Job_Number"
                    ...>
                </TextBox>

                <Button
                    ...>

                    <Button.Style>
                        <Style TargetType="{x:Type Button}">
                            <Style.Triggers>
                                <MultiDataTrigger>
                                    <MultiDataTrigger.Conditions>
                                        <Condition Binding="{Binding Text, ElementName=Serial_Number, Converter={StaticResource StringToBoolean}}" Value="True"/>
                                        <Condition Binding="{Binding Text, ElementName=Job_Number, Converter={StaticResource StringToBoolean}}" Value="True"/>
                                    </MultiDataTrigger.Conditions>
                                    <Setter Property="IsEnabled" Value="True"/>
                                </MultiDataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Button.Style>

                </Button>
            </Grid>
        </Border>
    </DockPanel>

</UserControl>

問題:

テキストボックスに何かがある場合、コンバーターは true を返します。両方のテキストボックスに何かがある場合、両方のコンバーターが起動し、セッターが適用される必要があります。IsEnabledセッターでプロパティを False に設定すると、初期状態がアクティブ化されたボタンが非アクティブ化されるため、これが発生することがわかっています。

逆は起こりません。プロパティを True に設定してIsEnabledボタンは有効にならず、初期状態は非アクティブになっています (これは、ボタンで直接 IsEnabled プロパティを False に設定することで実現しました)。これがデフォルトの状態として機能し、セッターがそれをオーバーライドすると考えました。そうではないようです。

私が気づいたいくつかの奇妙な点:

2 番目の条件は、最初の条件が発生するまで発生しないようです。つまり、最初のテキスト ボックスに触れる前に 2 番目のテキスト ボックスにデータを入力すると、コンバーターはまったく起動しません。最初のテキストボックスにデータを入力すると、両方のコンバーターが起動します。

テキストボックスにデータが存在する場合にのみボタンを有効にする方法はありますか? (True/True = 有効、True/False = 無効、False/True = 無効、False/False = 無効) ケースのすべての組み合わせを実際に書き出す必要がありますか? これは、私の側のタイプミスまたは愚かな論理エラーの場合ですか? 現時点では、偏見のない目でこれを見ることは本当にできません。

4

1 に答える 1

2

に更新してみてStyleください

<Style TargetType="{x:Type Button}">
  <!-- New Bit -->
  <Setter Property="IsEnabled" Value="False"/>
  <!-- End of New Bit -->
    <Style.Triggers>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding Text, ElementName=Serial_Number, Converter={StaticResource StringToBoolean}}" Value="True"/>
                <Condition Binding="{Binding Text, ElementName=Job_Number, Converter={StaticResource StringToBoolean}}" Value="True"/>
            </MultiDataTrigger.Conditions>
            <Setter Property="IsEnabled" Value="True"/>
        </MultiDataTrigger>
    </Style.Triggers>
</Style>

ボタンで IsEnabled プロパティを False に直接設定することでこれを行いました

要素にプロパティを設定すると、WPF の優先順位により、Triggerそのプロパティの やデフォルトのセッターはほとんど非アクティブになります。

最後に、 を使用してプロパティを変更する場合は、常にプロパティのデフォルト値を割り当て、Triggerそのプロパティが要素自体に記載されていないことを確認することをお勧めします。

特定のケースでは、コンバーターを使用せずにこれを行うこともできます。

<StackPanel xmlns:sys="clr-namespace:System;assembly=mscorlib">
  <TextBox x:Name="tbOne" />
  <TextBox x:Name="tbTwo" />
  <Button Content="Some Button">
    <Button.Style>
      <Style TargetType="{x:Type Button}">
        <Setter Property="IsEnabled"
                Value="True" />
        <Style.Triggers>
          <DataTrigger Binding="{Binding ElementName=tbOne,
                                          Path=Text}"
                        Value="{x:Static sys:String.Empty}">
            <Setter Property="IsEnabled"
                    Value="False" />
          </DataTrigger>
          <DataTrigger Binding="{Binding ElementName=tbTwo,
                                          Path=Text}"
                        Value="{x:Static sys:String.Empty}">
            <Setter Property="IsEnabled"
                    Value="False" />
          </DataTrigger>
        </Style.Triggers>
      </Style>
    </Button.Style>
  </Button>
</StackPanel>
于 2013-06-28T16:04:38.397 に答える