Frage

Ich versuche, eine diagramming Anwendung in C # / WPF zu erstellen. Was ich für den Gang ist etwas ähnlich wie Microsoft Visio, obwohl ich nicht bin versucht, es zu klonen. Ich schrieb Art diese Frage als ich Codierung und einfach alle Fragen habe ich in sie, falls jemand hatte wird es nützlich finden. Ich habe zu hart denken vielleicht, aber ich fühle mich wie ich auf meiner Tastatur werfen könnte und besseren Code erzeugen, so fühlen sich frei, irgendwelche Vorschläge über jedes Detail, um Ihnen zu fangen (Grammatik ausgeschlossen: -))

Kurz gesagt:
Warum sind alle Elemente der Position (0,0)?

Code:

public class Diagram : MultiSelector
{
    public Diagram()
    {
        this.CanSelectMultipleItems = true;

        // The canvas supports absolute positioning
        FrameworkElementFactory panel = new FrameworkElementFactory(typeof(Canvas)); 
        this.ItemsPanel = new ItemsPanelTemplate(panel);


        // Tells the container where to position the items
        this.ItemContainerStyle = new Style();
        this.ItemContainerStyle.Setters.Add(new Setter(Canvas.LeftProperty, new Binding("X")));
        this.ItemContainerStyle.Setters.Add(new Setter(Canvas.TopProperty, new Binding("Y")));
    }

    protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
    {
        FrameworkElement contentitem = element as FrameworkElement;
        Binding leftBinding = new Binding("X");
        Binding topBinding = new Binding("Y");
        contentitem.SetBinding(Canvas.LeftProperty, leftBinding);
        contentitem.SetBinding(Canvas.TopProperty, topBinding);
        base.PrepareContainerForItemOverride(element, item);
    }

    public class DiagramItem : ContentControl
    {
        private Point _location;

        public DiagramItem()
        {
        }

        static DiagramItem()
        {

        }

        public Point Location
        {
            get { return _location; }
            set
            {
                _location = value;

            }
        }

        public double X
        {
            get { return _location.X; }
            set
            {
                _location.X = value;
            }
        }

        public double Y
        {
            get { return _location.Y; }
            set
            {
                _location.Y = value;
            }
        }
    }

//...

Ok, so die Idee ist, dass die Diagramm: Items legt den Artikel auf einer Leinwand Platte an der Position in dem Artikel DiagramItem.Location definiert. IOW, wenn ich die X-Eigenschaft in einer DiagramItem das Diagramm bewegt sich das Element auf der x-Achse zu ändern.

Hinweis: Multiselector von Items und Selector abgeleitet und nur hier wird verwendet, weil ich das angezeigte Element muß wählbar sein

.

Bitte beachten Sie, dass ich würde es vorziehen, nicht XAML wenn möglich zu verwenden.


In lang:
Ein Diagramm Beispiel, wie vom Benutzer gesehen hat diese Anforderungen:

  1. Hat mehrere DiagramItems.
  2. Der Benutzer kann mehrere DiagramItems wählen.
  3. DiagramItems Größe verändert werden kann, gedreht und überall auf dem Diagramm gezogen werden.
  4. Mögliche zwischen DiagramItems mit der Tastatur navigieren.

Ich habe im Grunde zwei und möglicherweise drei Klassen relevant zu dieser Frage.

  • Diagramm erweitert System.Windows.Controls.Primitives Multiselector . Selector: Items
  • DiagramItem erweitert Content oder eine andere Steuerung

Die Diagram.ItemsPanel auch bekannt als die Anzeigetafel, die die Elemente angezeigt werden soll eine Platte sein, die absolute Positionierung unterstützt, wie die Leinwand .

Wie soll ich eine Klasse implementieren von Multiselector abgeleitet und welche Ressourcen können Sie an diesem Punkt sind auf diese Frage relevant?

Was muss man beachten, wenn Sie eine benutzerdefinierte Implementierung Multiselector / Items?


Ressourcen:

Ich habe nur sehr wenige Ressourcen relevant für mein Problem gefunden, aber dann wieder bin ich nicht sicher, was ich soll zu suchen. Ich habe den Quellcode für ListBox und ListBoxItem mit Reflektor lesen, aber nicht fand es sehr nützlich.

Weitere Informationen:

War es hilfreich?

Lösung

OK, offensichtlich kann dies leicht mit Bindungen und die Eigenschaft Rahmen erreicht werden.

    public class Diagram : MultiSelector
    {
        public Diagram()
        {
           this.CanSelectMultipleItems = true;


            // The canvas supports absolute positioning
            FrameworkElementFactory panel = new FrameworkElementFactory(typeof(Canvas)); 
            this.ItemsPanel = new ItemsPanelTemplate(panel);


            // Tells the container where to position the items
           this.ItemContainerStyle = new Style();
            this.ItemContainerStyle.Setters.Add(new Setter(Canvas.LeftProperty, new Binding("X")));
            this.ItemContainerStyle.Setters.Add(new Setter(Canvas.TopProperty, new Binding("Y")));
        }


        protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
        {
            FrameworkElement contentitem = element as FrameworkElement;

            Binding leftBinding = new Binding("XProperty");
            leftBinding.Source = contentitem;

            Binding topBinding = new Binding("YProperty");
            topBinding.Source = contentitem;

            contentitem.SetBinding(Canvas.LeftProperty, leftBinding);
            contentitem.SetBinding(Canvas.TopProperty, topBinding);
            base.PrepareContainerForItemOverride(element, item);
        }





 public class DiagramItem : ContentControl
 {
       public static readonly DependencyProperty XProperty;
       public static readonly DependencyProperty YProperty;
       public static readonly RoutedEvent SelectedEvent;
       public static readonly RoutedEvent UnselectedEvent;
       public static readonly DependencyProperty IsSelectedProperty;

       public DiagramItem()
       {
       }

       static DiagramItem()
       {
            XProperty = DependencyProperty.Register("XProperty", typeof(Double), typeof(DiagramItem));
            YProperty = DependencyProperty.Register("YProperty", typeof(Double), typeof(DiagramItem));
            SelectedEvent = MultiSelector.SelectedEvent.AddOwner(typeof(DiagramItem));
            UnselectedEvent = MultiSelector.SelectedEvent.AddOwner(typeof(DiagramItem));
            IsSelectedProperty = MultiSelector.IsSelectedProperty.AddOwner(typeof(DiagramItem));

       }


       public Double X
       {
            get
            {
                return (Double)this.GetValue(XProperty);
            }

            set
            {
                this.SetValue(XProperty, value);
            }
       }

       public Double Y
       {
            get
            {
                return (Double)this.GetValue(YProperty);
            }
            set
            {
                 this.SetValue(YProperty, value);
            }
        }

        public Point Location
        {
            get
            {
                return new Point(X, Y);
            }

            set
            {
                this.X = value.X;
                this.Y = value.Y;
            }
        }

    }

Die Magie ist in der richtigen Verwendung von Bingings, der Schlüssel für die ContentItem als Quelle hinzuzufügen war. Der nächste Schritt ist natürlich die große Auswahl an handhaben, aber das ist eine andere Frage auf seine eigene.

Andere Tipps

Wenn es keine Hilfe, ich schrieb Artikel ein Code-Projekt basiert auf meiner Grafik und diagramming Custom Control namens Networkview:

http: // www. codeproject.com/Articles/182683/NetworkView-A-WPF-custom-control-for-visualizing-a

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top