C# 带有MultiDataTrigger和NullToBoolConverter的XAML

C# 带有MultiDataTrigger和NullToBoolConverter的XAML,c#,.net,wpf,xaml,triggers,C#,.net,Wpf,Xaml,Triggers,如果所有的文本框都有一个值,但它不起作用,并且我也不知道为什么,我会尝试使用一个按钮来启用它 NullToBoolConverter.cs public class NullToBoolConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { TypeConverter con

如果所有的文本框都有一个值,但它不起作用,并且我也不知道为什么,我会尝试使用一个按钮来启用它

NullToBoolConverter.cs

public class NullToBoolConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        TypeConverter converter = TypeDescriptor.GetConverter(typeof(bool));
        bool nullResult = false;
        if (parameter != null)
            nullResult = (bool)converter.ConvertFrom(parameter);
        if (value == null)
            return nullResult;
        else
            return !nullResult;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Binding.DoNothing;
    }
}
XAML资源中心

<ex:NullToBoolConverter x:Key="NullToBoolConverter"/>

<Style x:Key="okButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="IsEnabled" Value="False" />
    <Style.Triggers>
        <MultiDataTrigger>
            <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding Hostadress, Converter={StaticResource NullToBoolConverter}, UpdateSourceTrigger=PropertyChanged}" Value="True" />
                <Condition Binding="{Binding UserBox, Converter={StaticResource NullToBoolConverter}, UpdateSourceTrigger=PropertyChanged}" Value="True"  />
                <Condition Binding="{Binding PasswordTextBox, Converter={StaticResource NullToBoolConverter}, UpdateSourceTrigger=PropertyChanged}" Value="True" />
                <Condition Binding="{Binding PortBox, Converter={StaticResource NullToBoolConverter}, UpdateSourceTrigger=PropertyChanged}" Value="True" />
            </MultiDataTrigger.Conditions>
            <Setter Property="IsEnabled" Value="True" />
        </MultiDataTrigger>
    </Style.Triggers>
</Style>

我尝试了您的代码,我发现您唯一的问题是,您只是将值与
null
进行比较,而不是与
string.Empty
进行比较。试试这个

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    TypeConverter converter = TypeDescriptor.GetConverter(typeof(bool));
    bool nullResult = false;
    if (parameter != null)
        nullResult = (bool)converter.ConvertFrom(parameter);
    if (value == null || value.ToString() == string.Empty)
        return nullResult;
    else
        return !nullResult;
}

我尝试了您的代码,但我发现您唯一的问题是,您只是将值与
null
进行比较,而不是与
string.Empty
进行比较。试试这个

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    TypeConverter converter = TypeDescriptor.GetConverter(typeof(bool));
    bool nullResult = false;
    if (parameter != null)
        nullResult = (bool)converter.ConvertFrom(parameter);
    if (value == null || value.ToString() == string.Empty)
        return nullResult;
    else
        return !nullResult;
}

我把你的转换器换成了这个,因为它看起来简单多了

public class NullToBoolConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            return false;

        string currentValue = value.ToString();

        if (string.IsNullOrWhiteSpace(currentValue))
            return false;

        return true;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Binding.DoNothing;
    }
}
那么你的XAML风格应该是这样的

    <ex:NullToBoolConverter
        x:Key="NullToBoolConverter" />

    <Style
        x:Key="okButtonStyle"
        TargetType="{x:Type Button}">
        <Setter
            Property="IsEnabled"
            Value="False" />
        <Style.Triggers>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition
                        Binding="{Binding ElementName=Hostadress, Path=Text, Converter={StaticResource NullToBoolConverter}, UpdateSourceTrigger=PropertyChanged}"
                        Value="True" />
                    <Condition
                        Binding="{Binding ElementName=UserBox, Path=Text, Converter={StaticResource NullToBoolConverter}, UpdateSourceTrigger=PropertyChanged}"
                        Value="True" />
                    <Condition
                        Binding="{Binding ElementName=PasswordTextBox, Path=Text, Converter={StaticResource NullToBoolConverter}, UpdateSourceTrigger=PropertyChanged}"
                        Value="True" />
                    <Condition
                        Binding="{Binding ElementName=PortBox, Path=Text, Converter={StaticResource NullToBoolConverter}, UpdateSourceTrigger=PropertyChanged}"
                        Value="True" />
                </MultiDataTrigger.Conditions>
                <Setter
                    Property="IsEnabled"
                    Value="True" />
            </MultiDataTrigger>
        </Style.Triggers>
    </Style>

调试工作正常,在所有文本框中键入将启用该按钮


请注意,我将绑定语句更改为使用ElementName和Path。

我将您的转换器更改为此,因为它看起来简单多了

public class NullToBoolConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            return false;

        string currentValue = value.ToString();

        if (string.IsNullOrWhiteSpace(currentValue))
            return false;

        return true;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Binding.DoNothing;
    }
}
那么你的XAML风格应该是这样的

    <ex:NullToBoolConverter
        x:Key="NullToBoolConverter" />

    <Style
        x:Key="okButtonStyle"
        TargetType="{x:Type Button}">
        <Setter
            Property="IsEnabled"
            Value="False" />
        <Style.Triggers>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition
                        Binding="{Binding ElementName=Hostadress, Path=Text, Converter={StaticResource NullToBoolConverter}, UpdateSourceTrigger=PropertyChanged}"
                        Value="True" />
                    <Condition
                        Binding="{Binding ElementName=UserBox, Path=Text, Converter={StaticResource NullToBoolConverter}, UpdateSourceTrigger=PropertyChanged}"
                        Value="True" />
                    <Condition
                        Binding="{Binding ElementName=PasswordTextBox, Path=Text, Converter={StaticResource NullToBoolConverter}, UpdateSourceTrigger=PropertyChanged}"
                        Value="True" />
                    <Condition
                        Binding="{Binding ElementName=PortBox, Path=Text, Converter={StaticResource NullToBoolConverter}, UpdateSourceTrigger=PropertyChanged}"
                        Value="True" />
                </MultiDataTrigger.Conditions>
                <Setter
                    Property="IsEnabled"
                    Value="True" />
            </MultiDataTrigger>
        </Style.Triggers>
    </Style>

调试工作正常,在所有文本框中键入将启用该按钮


请注意,我更改了绑定语句以使用ElementName和Path。

我简化了一点代码:

[ValueConversion(typeof(object), typeof(bool))]
public class NullToBoolValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var result = value == null;
        return parameter != null ? !result : result;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}

我简化了一点代码:

[ValueConversion(typeof(object), typeof(bool))]
public class NullToBoolValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var result = value == null;
        return parameter != null ? !result : result;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}

我对转换器使用了
,但什么也没发生,我仍然有一个禁用的控件。我还为转换器设置了断点,但从未在那里停留过。我猜问题在于
按钮的
DataContext
。将它与我的示例进行比较,上传到这里:问题在于DataTriggers中的绑定。我下面的代码有效。@Eclipsed4utoo:
样式应用于
按钮
,因此DataTriggers中的绑定将使用与
按钮
相同的
DataContext
。所以,这一切都归结于它的使用方式。我将
与您的转换器一起使用,但什么都没有发生,我仍然有一个禁用的控件。我还为转换器设置了断点,但从未在那里停留过。我猜问题在于
按钮的
DataContext
。将它与我的示例进行比较,上传到这里:问题在于DataTriggers中的绑定。我下面的代码有效。@Eclipsed4utoo:
样式应用于
按钮
,因此DataTriggers中的绑定将使用与
按钮
相同的
DataContext
。所以这一切都取决于它的用途。我只是想知道。你将Meleak的帖子标记为答案,但在评论中说它不起作用。那么,如果它不能解决您的问题,那么答案到底是什么呢?只是想知道。他上传了他的演示项目,发现我必须设置我的datacontext;-)我只是想知道。你将Meleak的帖子标记为答案,但在评论中说它不起作用。那么,如果它不能解决您的问题,那么答案到底是什么呢?只是想知道。他上传了他的演示项目,发现我必须设置我的datacontext;-)进一步简化:
公共对象转换(对象值,类型targetType,对象参数,文化信息文化){return!(参数==null^value==null);}
进一步简化:
公共对象转换(对象值,类型targetType,对象参数,文化信息文化){return!(参数==null^value==null);}