WPF Render Event Not Drawing Anything

后端 未结 1 480
情书的邮戳
情书的邮戳 2021-01-13 14:57

I\'m trying to convert some WinForm code to WPF for a pipe network drawing app. I\'ve been basing it off this paint app article:

http://www.codeproject.com/Articles

相关标签:
1条回答
  • 2021-01-13 15:33

    Look this is a simple example I made in 20 minutes:

    XAML:

    <Window x:Class="NodesEditor.MainWindow"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:NodesEditor"
            Title="Window1" Height="800" Width="800" x:Name="view">
        <Grid Margin="10">
            <Grid.Resources>
                <!-- This CompositeCollection basically Concatenates the Nodes and Connectors in a single one -->
                <CompositeCollection x:Key="Col">
                    <CollectionContainer Collection="{Binding DataContext.Connectors,Source={x:Reference view}}"/>
                    <CollectionContainer Collection="{Binding DataContext.Nodes,Source={x:Reference view}}"/>
                </CompositeCollection>
    
                <!-- This is the DataTemplate that will be used to render the Node class -->
                <DataTemplate DataType="{x:Type local:Node}">
                    <Thumb DragDelta="Thumb_Drag">
                        <Thumb.Template>
                            <ControlTemplate TargetType="Thumb">
                                <Ellipse Height="10" Width="10" Stroke="Black" StrokeThickness="1" Fill="Blue"
                                         Margin="-5,-5,5,5" x:Name="Ellipse"/>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsDragging" Value="True">
                                        <Setter TargetName="Ellipse" Property="Fill" Value="Yellow"/>
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Thumb.Template>
                    </Thumb>
                </DataTemplate>
    
                <!-- This is the DataTemplate that will be used to render the Connector class -->
                <DataTemplate DataType="{x:Type local:Connector}">
                    <Line Stroke="Black" StrokeThickness="1"
                          X1="{Binding Start.X}" Y1="{Binding Start.Y}"
                          X2="{Binding End.X}" Y2="{Binding End.Y}"/>
                </DataTemplate>
            </Grid.Resources>
    
            <!-- This Border serves as a background and the VisualBrush used to paint its background serves as the "Snapping Grid" -->
            <!-- The "Snapping" Actually occurs in the Node class (see Node.X and Node.Y properties), it has nothing to do with any UI Elements -->
            <Border>
                <Border.Background>
                    <VisualBrush TileMode="Tile"
                                 Viewport="0,0,50,50" ViewportUnits="Absolute" 
                                 Viewbox="0,0,50,50" ViewboxUnits="Absolute">
                        <VisualBrush.Visual>
                            <Rectangle Stroke="Darkgray" StrokeThickness="1" Height="50" Width="50"
                                       StrokeDashArray="5 3"/>
                        </VisualBrush.Visual>
                    </VisualBrush>
                </Border.Background>
            </Border>
            <ItemsControl>
                <ItemsControl.ItemsSource>
                    <StaticResource ResourceKey="Col"/>
                </ItemsControl.ItemsSource>
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Canvas IsItemsHost="True"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemContainerStyle>
                    <Style TargetType="ContentPresenter">
                        <Setter Property="Canvas.Left" Value="{Binding X}"/>
                        <Setter Property="Canvas.Top" Value="{Binding Y}"/>
                    </Style>
                </ItemsControl.ItemContainerStyle>
            </ItemsControl>
        </Grid>
    </Window>
    

    Code Behind:

    using System.Collections.Generic;
    using System.Linq;
    using System.Windows;
    using System.Windows.Controls.Primitives;
    
    namespace NodesEditor
    {
        public partial class MainWindow : Window
        {
            public List<Node> Nodes { get; set; }
            public List<Connector> Connectors { get; set; }
    
            public MainWindow()
            {
                InitializeComponent();
    
                Nodes = NodesDataSource.GetRandomNodes().ToList();
                Connectors = NodesDataSource.GetRandomConnectors(Nodes).ToList();
    
                DataContext = this;
            }
    
            private void Thumb_Drag(object sender, DragDeltaEventArgs e)
            {
                var thumb = sender as Thumb;
                if (thumb == null)
                    return;
    
                var data = thumb.DataContext as Node;
                if (data == null)
                    return;
    
                data.X += e.HorizontalChange;
                data.Y += e.VerticalChange;
            }
        }
    }
    

    Data Model:

    public class Node: INotifyPropertyChanged
        {
            private double _x;
            public double X
            {
                get { return _x; }
                set
                {
                    //"Grid Snapping"
                    //this actually "rounds" the value so that it will always be a multiple of 50.
                    _x = (Math.Round(value / 50.0)) * 50;
                    OnPropertyChanged("X");
                }
            }
    
            private double _y;
            public double Y
            {
                get { return _y; }
                set
                {
                    //"Grid Snapping"
                    //this actually "rounds" the value so that it will always be a multiple of 50.
                    _y = (Math.Round(value / 50.0)) * 50;
                    OnPropertyChanged("Y");
                }
            }
    
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected virtual void OnPropertyChanged(string propertyName)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    
    public class Connector
    {
        public Node Start { get; set; }
        public Node End { get; set; }
    }
    

    Random Data Source (To fill the example with something)

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace NodesEditor
    {
        public static class NodesDataSource
        {
            public static Random random = new Random();
    
            public static Node GetRandomNode()
            {
                return new Node
                    {
                        X = random.Next(0,500),
                        Y = random.Next(0,500)
                    };
    
            }
    
            public static IEnumerable<Node> GetRandomNodes()
            {
                return Enumerable.Range(5, random.Next(6, 10)).Select(x => GetRandomNode());
            }
    
            public static Connector GetRandomConnector(IEnumerable<Node> nodes)
            {
                return new Connector { Start = nodes.FirstOrDefault(), End = nodes.Skip(1).FirstOrDefault() };
            }
    
            public static IEnumerable<Connector> GetRandomConnectors(List<Node> nodes)
            {
                var result = new List<Connector>();
                for (int i = 0; i < nodes.Count() - 1; i++)
                {
                    result.Add(new Connector() {Start = nodes[i], End = nodes[i + 1]});
                }
                return result;
            }
        }
    }
    

    This is what it looks like in my Computer:

    enter image description here

    0 讨论(0)
提交回复
热议问题