无法将UserControl颜色属性绑定到ToggleButton背景

时间:2016-08-13 10:49:19

标签: c# wpf

我无法理解......我制作了一个由togglebutton制作的简单UserControl来打开一个包含CustomControl,一个颜色选择器的弹出窗口。

只有在为切换背景颜色写入颜色名称时才能打开/关闭弹出窗口没问题。

但是,如果我尝试绑定UserControl Color属性,以便在弹出窗口关闭时查看所选颜色,则切换按钮不会显示且根本不起作用。

我一定错过了一个细节,因为我觉得它很简单:

<ToggleButton 
    x:Name="OpenColorPicker"  
    Style="{DynamicResource ToggleColorPickerStyle}" 
    Background="{Binding DataContext.SelectedColor, ElementName=ColorPickerWidget, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
    />

不幸的是没有..

以下是完整的XAML文件:

<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
mc:Ignorable="d" 
x:Class="CMiX.ColorSelector"  
xmlns:colorPicker="clr-namespace:ColorPicker;assembly=ColorPicker"
xmlns:local="clr-namespace:CMiX"
Height="Auto" Width="Auto" d:DesignWidth="44.533" d:DesignHeight="24.933"
x:Name="ColorPickerWidget">

<UserControl.Resources>
    <SolidColorBrush x:Key="BaseDarkColor" Color="#FF323232"/>
    <local:ColorToBrushConverter x:Key="ColorToBrush"/>
    <Style x:Key="ToggleColorPickerStyle" TargetType="{x:Type ToggleButton}">
        <Setter Property="FocusVisualStyle">
            <Setter.Value>
                <Style>
                    <Setter Property="Control.Template">
                        <Setter.Value>
                            <ControlTemplate>
                                <Rectangle Margin="2" SnapsToDevicePixels="True" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </Setter.Value>
        </Setter>
        <Setter Property="Background" Value="Red"/>
        <Setter Property="BorderBrush" Value="Transparent"/>
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="BorderThickness" Value="0"/>
        <Setter Property="HorizontalContentAlignment" Value="Center"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="Padding" Value="1"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ToggleButton}">
                    <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                        <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>

<Grid>
    <ToggleButton x:Name="OpenColorPicker"  Style="{DynamicResource ToggleColorPickerStyle}" Background="{Binding DataContext.SelectedColor, ElementName=ColorPickerWidget, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    <Popup x:Name="PopupColorPicker" SnapsToDevicePixels="True" AllowsTransparency="True" IsOpen="{Binding IsChecked, ElementName=OpenColorPicker}" StaysOpen="True" Placement="Right">
        <Border Margin="20, 20, 0, 20" Padding="5">
            <colorPicker:ColorPicker x:Name="ColorPicker" Background="{StaticResource BaseDarkColor}" Width="420" Height="210" SelectedColor="{Binding DataContext.SelectedColor, ElementName=ColorPickerWidget, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
                <colorPicker:ColorPicker.Effect>
                    <DropShadowEffect  BlurRadius="20" Opacity="1" Direction="0"/>
                </colorPicker:ColorPicker.Effect>
            </colorPicker:ColorPicker>
        </Border>
    </Popup>
</Grid>

名为ColorPickerWidget的UserControl具有以下属性:

public static readonly DependencyProperty
SelectedColorProperty = DependencyProperty.Register("SelectedColor", typeof(Color), typeof(ColorSelector));
public Color SelectedColor
{
    get { return (Color)GetValue(SelectedColorProperty); }
    set { SetValue(SelectedColorProperty, value); }
}

有什么想法吗?

谢谢

编辑__

我试过了:

<ToggleButton x:Name="OpenColorPicker" Background="{Binding SelectedColor, ElementName=ColorPicker, Converter={StaticResource ColorToBrush}}"/>

使用此转换器:

public class ColorToBrushConverter : IValueConverter
{
    SolidColorBrush _red = new SolidColorBrush(), 
                    _green = new SolidColorBrush(), 
                    _blue = new SolidColorBrush(), 
                    _alpha = new SolidColorBrush(),
                    _all = new SolidColorBrush();

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var color = (Color)value;
        switch ((string)parameter)
        {
            case "r":
                _red.Color = Color.FromRgb(color.R, 0, 0);
                return _red;
            case "g":
                _green.Color = Color.FromRgb(0, color.G, 0);
                return _green;
            case "b":
                _blue.Color = Color.FromRgb(0, 0, color.B);
                return _blue;
            case "a":
                _alpha.Color = Color.FromArgb(color.A,
                128, 128, 128);
                return _alpha;
            case "all":
                _all.Color = Color.FromArgb(color.A, color.R, color.G, color.B);
                return _all;

        }
        return Binding.DoNothing;
    }

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

但同样的问题,按钮背景不是颜色。

1 个答案:

答案 0 :(得分:1)

绑定到ToggleButton.Background时存在一些问题。首先,您要绑定到ColorPicker DataContext.SelectedColorDataContext是视图模型。它可能与DataContext具有相同的ToggleButton。所以你不需要去ColorPicker找到它。但是ColorPicker无论如何都不会将SelectedColor绑定到viewmodel属性,所以这可能只是一个误解。摆脱该绑定中的DataContext,它只是将一个野鹅追逐发送到无处。

然后你的名字错了。您将颜色选择器"ColorPicker"命名为,但是您告诉绑定要查找"ColorPickerWidget"Mode=TwoWay毫无意义,因为ToggleButton无法更改Background并将颜色发送回颜色选择器。但它的背景并不是一种颜色;它是Brush。所以这不可行。

因为它期待Brush,你需要一个转换器来将颜色转换为画笔。 XAML中的Brush属性非常迷惑,因为您可以为它们提供字符串"Green""#882266aa"等内容,并且它们可以正常工作。但那是因为他们与幕后的TypeConverter相关联,将这些字符串转换为Brush。但是,如果将Color值绑定到属性,那么这不起作用。它不直观明显。

此绑定是否适用于ToggleButton.Background

Background="{Binding SelectedColor, ElementName=ColorPicker, Converter={StaticResource ColorToBrush}}"
相关问题