WPF将布尔绑定转换为是或否的

时间:2017-03-22 19:42:23

标签: c# wpf binding boolean

正如我的标题所说我需要在我的DataGrid中写入而不是True或False是/否我从数据库得到的布尔值,

我一直在研究,并且我找到了一些帮助者:

public class BoolToValueConverter<T> : IValueConverter
{
    public T FalseValue { get; set; }
    public T TrueValue { get; set; }

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null)
            return FalseValue;
        else
            return (bool)value ? TrueValue : FalseValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value != null ? value.Equals(TrueValue) : false;
    }
}

但问题是如何在XAML中正确应用它,

我尝试将此添加到我的XAML中:

<local:BoolToStringConverter x:Key="BooleanToStringConverter" FalseValue="No" TrueValue="Yes" />

但是我得到了以下错误:

  

错误2&#39;&#39;本地&#39;是未声明的前缀。第13行,第10位。&#39; XML   无效。

     

错误4 Windows不支持BoolToStringConverter   Presentation Foundation(WPF)项目。

     

错误7&#34;键&#34;属性只能用于元素   包含在&#34; IDictionary&#34;。

所以我的问题是如何让这个在我的XAML中运行,可能我需要包含一些东西或其他什么,我对WPF真的很新,所以现在我很难找到解决方案:/

反正 多谢你们, 干杯

编辑:(我的XAML代码)

<Window x:Class="MyProject.Forms.Products"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        Title="Products" Height="768" Width="1024">
    <Grid>
          <Grid.RowDefinitions>
                        <RowDefinition Height="60" />
                        <RowDefinition />
                        <RowDefinition Height="60" />
          </Grid.RowDefinitions>

        <DataGrid Grid.Row="1" IsReadOnly="True" Name="dtgProducts" ScrollViewer.CanContentScroll="False" EnableRowVirtualization ="True" EnableColumnVirtualization = "True" HorizontalGridLinesBrush="#d3d3d3" AlternatingRowBackground="#E0E4E5" AlternationCount="2"  GridLinesVisibility="Horizontal" FontSize="16" RowHeight="30" SelectionUnit="FullRow" Background="White" Margin="5,0" AutoGenerateColumns="False" ItemsSource="{Binding}" RowHeaderWidth="0" VerticalGridLinesBrush="#0091EA" CanUserAddRows="False">
                <DataGrid.CellStyle>
                    <StaticResource ResourceKey="DataGridCentering"/>
                </DataGrid.CellStyle>

                <DataGrid.Resources>

                    <Style TargetType="{x:Type DataGridColumnHeader}">
                        <Setter Property="Background" Value="#0091EA"/>
                        <Setter Property="Opacity" Value="1"/>
                        <Setter Property="Foreground" Value="White"/>
                        <Setter Property="HorizontalContentAlignment" Value="Center" />
                        <Setter Property="FontSize" Value="16"/>
                        <Setter Property="FontFamily" Value="Arial"/>
                        <Setter Property="Height" Value="40"/>
                    </Style>

                    <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" 
                   Color="LightBlue"/>

                </DataGrid.Resources>   

                <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding ProductTitle}"        Header="ProductName"  Foreground="Black"  FontSize="15" FontFamily="Verdana"  Width="10*"/>
                <DataGridTextColumn Binding="{Binding IsNew}" Header="Is it new product(Yes/No)."  Foreground="Black"  FontSize="15" FontFamily="Verdana"  Width="10*"/>
            </DataGrid.Columns>

    </DataGrid>

    </Grid>

</Window>

编辑:

包括DATAGRID的资源

enter image description here

包含在文件顶部:

enter image description here

1 个答案:

答案 0 :(得分:1)

Clemens' comment says类似,您需要添加必要的XML名称空间声明,提供非泛型类型,并适当地声明您的转换器对象(它可以使用x:Key...进入字典,或者你可以内联指定它。

更改看起来像这样(我省略了所有与您的问题没有直接关系的XAML):

<Window x:Class="MyProject.Forms.Products"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        xmlns:local="clr-namespace:MyProject.Forms"
        Title="Products" Height="768" Width="1024">
    <Grid>
        <DataGrid ItemsSource="{Binding}">
            <DataGrid.Resources>
                <local:BoolToStringConverter x:Key="BooleanToStringConverter"
                                             FalseValue="No" TrueValue="Yes" />
            </DataGrid.Resources>   
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding IsNew, Converter={StaticResource BooleanToStringConverter}"
                                    Header="Is it new product(Yes/No)."/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

请注意添加到xmlns:local...元素的Window声明以及<local:BoolToStringConverter.../>元素中DataGrid.Resources元素的位置。

为了它的价值,因为在资源声明中设置了TrueValueFalseValue属性,我实际上会为资源提供更多描述密钥,例如"BooleanToYesNoConverter"

我注意到您的C#示例显示了一个名为BoolToValueConverter<T>的类,而您在XAML中使用的类型名称是BoolToStringConverter。这很好,只要您通过专门化通用子类来修复泛型类型问题。你可以轻松做到:

class BoolToStringConverter : BoolToValueConverter<string> { }

通过上述更改,您想要的一切都可以正常工作。但是,我建议对BoolToValueConverter<T>执行略有不同的实现:

class BoolToValueConverter<T> : IValueConverter
{
    public T TrueValue { get; set; }
    public T FalseValue { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value == null ? FalseValue : ((bool)value ? TrueValue : FalseValue);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // Note: this implementation precludes the use of "null" as the
        // value for TrueValue. Probably not an issue in 99.94% of all cases,
        // but something to consider, if one is looking to make a truly 100%
        // general-purpose class here.
        return value != null && EqualityComparer<T>.Default.Equals((T)value, TrueValue);
    }
}

即,使用EqualityComparer<T>.Default.Equals()进行相等比较。这比使用虚拟object.Equals()覆盖更有效,特别是对于值类型(在您的示例中不是问题,但可能在其他情况下)。