2010-11-16 33 views
0

Je travaille sur un projet qui est une application WPF "Paint" de base. J'ai trois options, dessiner une ellipse, dessiner une ligne, ou dessiner une «forme» (une ligne où les sections fermées sont remplies). Ces trois options sont représentées avec des boutons radio. J'ai jusqu'à cette partie de travail. Voici une capture d'écran par exemple:Création et utilisation d'un nouveau pinceau ou d'une nouvelle couleur à l'aide des curseurs et des propriétés de dépendance en C#

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

Fondamentalement, ce que je dois faire maintenant, lorsque l'utilisateur change les curseurs pour R, G, B et A (opacité/alpha), une petite zone de prévisualisation montrant la La nouvelle couleur doit être mise à jour et cette couleur doit être définie comme couleur de ligne ou de remplissage, selon le groupe de curseurs modifié. Tout cela doit être fait avec la liaison de données.

Je ne suis pas vraiment sûr de la meilleure approche de ce problème. Devrais-je avoir des valeurs individuelles pour chaque curseur (RGBA) et passer ces valeurs dans Color.FromArgb (R, G, B, A) ??

EDIT: Voici mon code

using System; en utilisant System.Collections.Generic; en utilisant System.Linq; en utilisant System.Text; en utilisant System.Windows; en utilisant System.Windows.Controls; en utilisant System.Windows.Data; en utilisant System.Windows.Documents; en utilisant System.Windows.Input; en utilisant System.Windows.Media; en utilisant System.Windows.Media.Imaging; en utilisant System.Windows.Navigation; en utilisant System.Windows.Shapes; en utilisant 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) 
     { 

     } 
    } 
} 

et voici mon 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> 

Répondre

1

Je ne sais pas si cela est la meilleure façon de le faire, mais vous pouvez avoir 5 propriétés publiques dans votre viewmodel: un pour Alpha, un pour Rouge, un pour Vert, un pour Bleu, et une structure définie par l'utilisateur que vous utiliserez pour "grouper" les 4 valeurs ensemble (appelons cela FillValue). Liez vos 4 curseurs à Alpha, Rouge, Vert et Bleu. Dans les setters pour ces 4 propriétés, vous définissez le champ correspondant dans FillValue puis appelez NotifyPropertyChanged pour les deux propriétés. Quelque chose comme ceci:

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

Rabattre la propriété de remplissage de votre aperçu pour FillValue et ajouter un convertisseur pour convertir le FillValue à une brosse. La liaison ressemblera à ceci:

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

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