代码之家  ›  专栏  ›  技术社区  ›  Sonny Boy

WPF-将背景色绑定到三个滑块?

  •  1
  • Sonny Boy  · 技术社区  · 14 年前

    我希望通过将标签的背景色绑定到三个滑动条来创建一个颜色选择工具,每个滑动条代表红色、蓝色或绿色。

    现在我知道如何将背景色绑定到单个字符串,但如何绑定到三个不同的控件?

    3 回复  |  直到 11 年前
        1
  •  4
  •   Abe Heidebrecht    14 年前

    你需要创造一个 IMultiValueConverter 类,并使用 MultiBinding . 如果你想绑一个 Control Background 属性,您需要返回 Brush . 一个天真的实现看起来像这样:

    public class BrushConverter : IMultiValueConverter
    {
        public object Converter(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            return new SolidColorBrush(
                Color.FromArgb(255, Convert.ToByte(values[0]), 
                    Convert.ToByte(values[1]), Convert.ToByte(values[2])));
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            // this can be implemented fairly easily
            throw new NotSupportedException();
        }
    }
    

    然后你可以这样使用它:

    <UserControl.Resources>
        <lcl:BrushConverter x:Key="brushConverter" />
    </UserControl.Resources>
    
    <StackPanel Orientation="Vertical">
        <StackPanel.Background>
            <MultiBinding Converter="{StaticResource brushConverter}">
                <Binding Path="Value" ElementName="r" />
                <Binding Path="Value" ElementName="g" />
                <Binding Path="Value" ElementName="b" />
            </MultiBinding>
        </StackPanel.Background>
        <Slider x:Name="r" Minimum="0" Maximum="255" IsSnapToTickEnabled="True" />
        <Slider x:Name="g" Minimum="0" Maximum="255" IsSnapToTickEnabled="True" />
        <Slider x:Name="b" Minimum="0" Maximum="255" IsSnapToTickEnabled="True" />
    </StackPanel>
    
        2
  •  0
  •   alpha-mouse    14 年前

    你应该用 MultiBinding . 您需要编写转换程序,将三个整数(红色、绿色和蓝色)转换为 Color .

        3
  •  0
  •   Dean Chalk    14 年前

    我最近用附加属性解决了这个问题

    这是完整的密码

        public static class BrushExtender
    {
        public readonly static DependencyProperty BrushProperty =
            DependencyProperty.RegisterAttached("Brush", typeof(Brush), 
            typeof(BrushExtender), new PropertyMetadata(Brushes.Black, DoBrushChanged));
    
        public readonly static DependencyProperty RedChannelProperty = 
            DependencyProperty.RegisterAttached("RedChannel", typeof(int), 
            typeof(BrushExtender), new PropertyMetadata(DoColorChangedRed));
    
        public readonly static DependencyProperty GreenChannelProperty = 
            DependencyProperty.RegisterAttached("GreenChannel", typeof(int), 
            typeof(BrushExtender), new PropertyMetadata(DoColorChangedGreen));
    
        public readonly static DependencyProperty BlueChannelProperty =
            DependencyProperty.RegisterAttached("BlueChannel", typeof(int),
            typeof(BrushExtender), new PropertyMetadata(DoColorChangedBlue));
    
        public readonly static DependencyProperty AlphaChannelProperty = 
            DependencyProperty.RegisterAttached("AlphaChannel", typeof(int),
            typeof(BrushExtender), new PropertyMetadata(DoColorChangedAlpha));
    
        public readonly static DependencyProperty ColourValueProperty =
            DependencyProperty.RegisterAttached("ColourValue", typeof(string),
            typeof(BrushExtender), new PropertyMetadata(DoValueChanged));
    
        public static void SetRedChannel(DependencyObject o, int value)
        {
            o.SetValue(RedChannelProperty, value);
        }
    
        public static void SetGreenChannel(DependencyObject o, int value)
        {
            o.SetValue(GreenChannelProperty, value);
        }
    
        public static void SetBlueChannel(DependencyObject o, int value)
        {
            o.SetValue(BlueChannelProperty, value);
        }
    
        public static void SetAlphaChannel(DependencyObject o, int value)
        {
            o.SetValue(AlphaChannelProperty, value);
        }
    
        public static void SetBrush(DependencyObject o, SolidColorBrush brush)
        {
            o.SetValue(BrushProperty, brush);
        }
    
        public static void SetColourValue(DependencyObject o, string value)
        {
            o.SetValue(ColourValueProperty, value);
        }
    
        private static void DoColorChangedRed(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var color = ((SolidColorBrush)d.GetValue(BrushProperty)).Color;
            DoColorChange(d, (int)e.NewValue, c => c.R, () => 
                Color.FromArgb(color.A, ((byte)(int)e.NewValue), color.G, color.B));
        }
    
        private static void DoColorChangedGreen(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var color = ((SolidColorBrush)d.GetValue(BrushProperty)).Color;
            DoColorChange(d, (int)e.NewValue, c => c.G, () => 
                Color.FromArgb(color.A, color.R, ((byte)(int)e.NewValue), color.B));
        }
    
        private static void DoColorChangedBlue(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var color = ((SolidColorBrush)d.GetValue(BrushProperty)).Color;
            DoColorChange(d, (int)e.NewValue, c => c.B, () => 
                Color.FromArgb(color.A, color.R, color.G, (byte)(int)e.NewValue));
        }
    
        private static void DoColorChangedAlpha(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var color = ((SolidColorBrush)d.GetValue(BrushProperty)).Color;
            DoColorChange(d, (int)e.NewValue, c => c.A, () => 
                Color.FromArgb((byte)(int)e.NewValue, color.R, color.G, color.B));
        }
    
        private static void DoColorChange(DependencyObject d, int newValue, Func<Color, int> colorCompare, 
            Func<Color> getColor)
        {
            var color = ((SolidColorBrush)d.GetValue(BrushProperty)).Color;
            if (colorCompare(color) == newValue)
                return;
            var newBrush = new SolidColorBrush(getColor());
            d.SetValue(BrushProperty, newBrush);
            d.SetValue(ColourValueProperty, newBrush.Color.ToString());
        }
    
        private static void DoValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var color = ((SolidColorBrush)d.GetValue(BrushProperty)).Color;
            if (color.ToString() == (string)e.NewValue)
                return;
            Color? newColour = null;
            try
            {
                newColour = (Color) ColorConverter.ConvertFromString((string)e.NewValue);
            }
            catch { }
            if (newColour == null)
                return;
            var newBrush = new SolidColorBrush(newColour.Value);
            d.SetValue(BrushProperty, newBrush);
        }
    
    
        private static void DoBrushChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue == e.OldValue)
                return;
            var colour = ((SolidColorBrush)e.NewValue).Color;
            d.SetValue(RedChannelProperty, (int)colour.R);
            d.SetValue(GreenChannelProperty, (int)colour.G);
            d.SetValue(BlueChannelProperty, (int)colour.B);
            d.SetValue(AlphaChannelProperty, (int)colour.A);
            d.SetValue(ColourValueProperty, colour.ToString());
        }
    }
    

    这是XAML

    <Window x:Class="ColourBlender.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:ColourBlender="clr-namespace:ColourBlender" 
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
    
        <TextBlock Text="Red" />
        <TextBlock Text="Green" Grid.Row="1" />
        <TextBlock Text="Blue" Grid.Row="2" />
        <TextBlock Text="Alpha" Grid.Row="3" />
    
        <Slider Name="redSlider" Grid.Column="1" Minimum="0" Maximum="255" Width="200" Height="20" 
                Grid.ColumnSpan="2" Value="{Binding ElementName=rect, 
                Path=(ColourBlender:BrushExtender.RedChannel), Mode=TwoWay}" />
        <Slider Name="greenSlider" Grid.Column="1" Grid.Row="1" Minimum="0" Maximum="255" Width="200" Height="20" 
                Grid.ColumnSpan="2" Value="{Binding ElementName=rect, 
                Path=(ColourBlender:BrushExtender.GreenChannel), Mode=TwoWay}"  />
        <Slider Name="blueSlider" Grid.Column="1" Grid.Row="2" Minimum="0" Maximum="255" Width="200" Height="20" 
                Grid.ColumnSpan="2" Value="{Binding ElementName=rect, 
                Path=(ColourBlender:BrushExtender.BlueChannel), Mode=TwoWay}"  />
        <Slider Name="alphaSlider" Grid.Column="1" Grid.Row="3" Minimum="0" Maximum="255" Width="200" Height="20" 
                Grid.ColumnSpan="2" Value="{Binding ElementName=rect, 
                Path=(ColourBlender:BrushExtender.AlphaChannel), Mode=TwoWay}"  />
    
        <Rectangle Fill="SandyBrown" Name="rect" Width="200" Height="50" Grid.Row="4" Grid.ColumnSpan="3" 
                Margin="0,20,0,10" ColourBlender:BrushExtender.Brush="{Binding RelativeSource={RelativeSource Self}, 
                Path=Fill, Mode=TwoWay}"/>
    
        <TextBlock Text="Colour Value" Margin="5,0,5,0" Grid.Row="5" HorizontalAlignment="Center"  />
        <TextBox Text="{Binding ElementName=rect, Path=(ColourBlender:BrushExtender.ColourValue), Mode=TwoWay}" 
                Margin="0,0,0,0" Grid.Row="5" Grid.Column="1" Width="100" HorizontalAlignment="Center" />
    
        <Button Content="Update" Grid.Row="5" Grid.Column="3" />
    </Grid>