Создание и использование новой кисти или цвета с помощью ползунков и свойств зависимостей в C #

Я работаю над проектом, который представляет собой базовое приложение WPF «Paint». У меня есть три варианта: нарисовать эллипс, нарисовать линию или нарисовать «фигуру» (линию, на которой закрашены закрытые участки). Эти три опции представлены переключателями. У меня до этой части работает. Вот пример скриншота:

http://i.stack.imgur.com/naPyI.jpg

В основном то, что мне нужно сделать сейчас, - это когда пользователь меняет ползунки для R, G, B и A (непрозрачность / альфа), небольшая область предварительного просмотра, показывающая новый цвет, должна быть обновлена, и этот цвет должен быть установлен как цвет линии или заливки, в зависимости от того, какая группа ползунков изменена. Все это нужно делать с привязкой данных.

Я не совсем уверен, как лучше всего подойти к этой проблеме. Должен ли я иметь индивидуальные значения для каждого ползунка (RGBA) и передавать эти значения в Color.FromArgb (R, G, B, A)?

РЕДАКТИРОВАТЬ: вот мой код

используя Систему; using System.Collections.Generic; using System.Linq; using System.Text; используя System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.ComponentModel;

namespace WpfPaint
{
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public bool start = false;
        public Ellipse myEllipse;
        public Polyline myLine;
        public Line myRegLine = new Line();
        public double xPos;
        public double yPos;

        public MainWindow()
        {
            InitializeComponent();
            MyCanvas.Children.Add(myRegLine);
        }

        private void MyCanvas_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            if (this.ellipse.IsChecked ?? false)
            {
                if (start)
                {
                    start = !start;
                    myEllipse = null;
                }
                else
                {
                    start = true;
                    myEllipse = new Ellipse();
                    xPos = e.GetPosition(MyCanvas).X;
                    yPos = e.GetPosition(MyCanvas).Y;

                    MyCanvas.Children.Add(myEllipse);
                    myEllipse.StrokeThickness = 5;
                    if (comboBox2.Text == "Red")
                    {
                        myEllipse.Fill = Brushes.Red;
                        fillR.Value = 255;
                        fillG.Value = 0;
                        fillB.Value = 0;
                    }
                    else if (comboBox2.Text == "Green")
                    {
                        myEllipse.Fill = Brushes.Green;
                        fillR.Value = 0;
                        fillG.Value = 255;
                        fillB.Value = 0;
                    }
                    else if (comboBox2.Text == "Blue")
                    {
                        myEllipse.Fill = Brushes.Blue;
                        fillR.Value = 0;
                        fillG.Value = 0;
                        fillB.Value = 255;
                    }

                    if (comboBox1.Text == "Red")
                    {
                        myEllipse.Stroke = Brushes.Red;
                        lineR.Value = 255;
                        lineG.Value = 0;
                        lineB.Value = 0;
                    }
                    else if (comboBox1.Text == "Green")
                    {
                        myEllipse.Stroke = Brushes.Green;
                        lineR.Value = 0;
                        lineG.Value = 255;
                        lineB.Value = 0;
                    }
                    else if (comboBox1.Text == "Blue")
                    {
                        myEllipse.Stroke = Brushes.Blue;
                        lineR.Value = 0;
                        lineG.Value = 0;
                        lineB.Value = 255;
                    }
                }
            }
            else
            {
                switch (e.ClickCount)
                {
                    case 1:
                        if (myLine == null)
                        {
                            myLine = new Polyline();
                            MyCanvas.Children.Add(myLine);
                            myLine.StrokeThickness = 5;
                            if (comboBox1.Text == "Red")
                            {

                                myLine.Stroke = Brushes.Red;
                                lineR.Value = 255;
                                lineG.Value = 0;
                                lineB.Value = 0;
                            }
                            else if (comboBox1.Text == "Green")
                            {

                                myLine.Stroke = Brushes.Green;
                                lineR.Value = 0;
                                lineG.Value = 255;
                                lineB.Value = 0;
                            }
                            else if (comboBox1.Text == "Blue")
                            {

                                myLine.Stroke = Brushes.Blue;
                                lineR.Value = 0;
                                lineG.Value = 0;
                                lineB.Value = 255;                                
                            }

                            if (this.shape.IsChecked ?? false)
                            {
                                if (comboBox2.Text == "Red")
                                {                                    
                                    myLine.Fill = Brushes.Red;
                                    fillR.Value = 255;
                                    fillG.Value = 0;
                                    fillB.Value = 0;
                                }
                                else if (comboBox2.Text == "Green")
                                {                                    
                                    myLine.Fill = Brushes.Green;
                                    fillR.Value = 0;
                                    fillG.Value = 255;
                                    fillB.Value = 0;
                                }
                                else if (comboBox2.Text == "Blue")
                                {                                    
                                    myLine.Fill = Brushes.Blue;
                                    fillR.Value = 0;
                                    fillG.Value = 0;
                                    fillB.Value = 255;
                                }
                            }


                        }

                        myLine.Points.Add(e.GetPosition(MyCanvas));
                        e.Handled = true;

                        break;
                    case 2:
                        myLine = null;
                        myRegLine = new Line();
                        MyCanvas.Children.Add(myRegLine);
                        break;

                }

            }
        }

        private void MyCanvas_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            if (start)
            {
                myEllipse.Height = Math.Abs(e.GetPosition(MyCanvas).X - xPos) * 2;
                myEllipse.Width = Math.Abs(e.GetPosition(MyCanvas).X - xPos) * 2;

                Canvas.SetTop(myEllipse, ((yPos) - myEllipse.Height / 2));
                Canvas.SetLeft(myEllipse, ((xPos) - myEllipse.Width / 2));
            }

            else
            {
                if (myLine != null)
                {
                    myRegLine.Stroke = myLine.Stroke;
                    myRegLine.X1 = myLine.Points.Last().X;
                    myRegLine.Y1 = myLine.Points.Last().Y;
                    myRegLine.X2 = e.GetPosition(MyCanvas).X;
                    myRegLine.Y2 = e.GetPosition(MyCanvas).Y;
                }
            }
        }

        private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

        }

        private void comboBox2_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

        }
    }
}

и вот мой XAML

<Window x:Class="WpfPaint.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <RadioButton Content="Line" Height="16" HorizontalAlignment="Left" Margin="12,10,0,0" Name="line" GroupName="options" VerticalAlignment="Top" IsChecked="True" />
    <RadioButton Content="Shape" Height="16" HorizontalAlignment="Left" Margin="12,34,0,0" Name="shape" GroupName="options" VerticalAlignment="Top" />
    <RadioButton Content="Ellipse" Height="16" HorizontalAlignment="Left" Margin="12,56,0,0" Name="ellipse" GroupName="options" VerticalAlignment="Top" />
    <Label Content="R" Margin="210,5,270,0" Height="31" VerticalAlignment="Top" />
    <Slider Height="23" HorizontalAlignment="Left" Margin="229,5,0,0" Name="lineR" VerticalAlignment="Top" Width="50" IsMoveToPointEnabled="False" Interval="1" IsSelectionRangeEnabled="False" Maximum="255" />
    <Slider Height="23" Margin="306,5,147,0" Name="lineG" VerticalAlignment="Top" IsMoveToPointEnabled="False" Interval="1" Maximum="255" />
    <Label Content="G" Margin="282,3,203,0" Height="30" VerticalAlignment="Top" />
    <Slider Height="23" HorizontalAlignment="Left" Margin="380,5,0,0" Name="lineB" VerticalAlignment="Top" Width="50" Interval="1" Maximum="255" />
    <Label Content="B" Margin="358,3,129,280"/>
    <Slider Height="23" HorizontalAlignment="Left" Margin="453,5,0,0" Name="lineA" VerticalAlignment="Top" Width="50" Interval="1" Maximum="255" Value="255" />
    <Label Content="A" Margin="428,3,56,0" Height="28" VerticalAlignment="Top" />
    <Canvas Name="MyCanvas" Background="#FFDADADA" Margin="0,76,0,0" PreviewMouseDown="MyCanvas_PreviewMouseDown" PreviewMouseMove="MyCanvas_PreviewMouseMove"></Canvas>
    <ComboBox Height="23" HorizontalAlignment="Left" Margin="127,5,0,0" Name="comboBox1" VerticalAlignment="Top" Width="70" SelectionChanged="comboBox1_SelectionChanged">
        <ComboBoxItem Content="Red" IsSelected="True" />
        <ComboBoxItem Content="Green" />
        <ComboBoxItem Content="Blue" />
    </ComboBox>
    <Label Content="Line" Height="28" HorizontalAlignment="Left" Margin="89,3,0,0" Name="label1" VerticalAlignment="Top" />
    <Label Content="Fill" Height="28" HorizontalAlignment="Left" Margin="96,42,0,0" Name="label2" VerticalAlignment="Top" />
    <ComboBox Height="23" HorizontalAlignment="Left" Margin="127,44,0,0" Name="comboBox2" VerticalAlignment="Top" Width="70" SelectionChanged="comboBox2_SelectionChanged">
        <ComboBoxItem Content="Red" IsSelected="True" />
        <ComboBoxItem Content="Green" />
        <ComboBoxItem Content="Blue" />
    </ComboBox>
    <Label Content="R" Margin="210,42,270,238" />
    <Slider Height="23" HorizontalAlignment="Left" IsMoveToPointEnabled="False" Margin="229,44,0,0" Name="fillR" VerticalAlignment="Top" Width="50" Maximum="255" Interval="1" />
    <Slider Height="23" HorizontalAlignment="Left" IsMoveToPointEnabled="False" Margin="306,44,0,0" Name="fillG" VerticalAlignment="Top" Width="50" Maximum="255" Interval="1" />
    <Label Content="G" Margin="282,40,203,241" />
    <Slider Height="23" HorizontalAlignment="Left" Margin="380,44,0,0" Name="fillB" VerticalAlignment="Top" Width="50" Maximum="255" Interval="1" />
    <Label Content="B" Margin="358,42,0,241" HorizontalAlignment="Left" Width="16" />
    <Slider Height="23" HorizontalAlignment="Left" Margin="453,44,0,0" Name="fillA" VerticalAlignment="Top" Width="50" Value="255" Interval="1" Maximum="255" />
    <Label Content="A" Margin="428,42,56,241" />
</Grid>


person Chris V.    schedule 16.11.2010    source источник


Ответы (1)


Не уверен, что это лучший способ сделать это, но у вас может быть 5 общедоступных свойств в вашей модели просмотра: одно для альфа, одно для красного, одно для зеленого, одно для синего и одна определяемая пользователем структура, которую вы будете использовать для группировки "4 значения вместе (назовем это FillValue). Привяжите свои 4 ползунка к альфа, красному, зеленому и синему. в установщиках для этих 4 свойств вы устанавливаете соответствующее поле в FillValue, а затем вызываете NotifyPropertyChanged для обоих свойств. Что-то вроде этого:

    public double Red
    {
        get { return FillValue.Red; }
        set
        {
            FillValue.Red = value;
            NotifyPropertyChanged("Red");
            NotifyPropertyChanged("FillValue");
        }
    }

Затем привяжите свойство fill вашего предварительного просмотра к FillValue и добавьте конвертер для преобразования FillValue в кисть. Привязка будет выглядеть примерно так:

<StackPanel>    
    <StackPanel.Resources>
        <RGBExample:FillValueCvtr x:Key="ColorCvtr"/>
    </StackPanel.Resources>

    <Rectangle Fill="{Binding FillValue, Converter={StaticResource ColorCvtr}}"/>
</StackPanel>
person ihatemash    schedule 16.11.2010