简体   繁体   English

WPF用户控件未更新路径

[英]WPF user control not updating path

I have a stripped down WPF example of a problem I am having in a much larger project. 我有一个简化的WPF示例,说明我在一个更大的项目中遇到的问题。 I have a user control called "UserControl1". 我有一个名为“ UserControl1”的用户控件。 The data context is set to self so I have dependency properties defined in the code-behind. 数据上下文设置为self,因此我在后面的代码中定义了依赖项属性。

In the control I have an ItemsControl. 在控件中,我有一个ItemsControl。 In the ItemsSource I have a CompositeCollection that contains a CollectionContainer and a Line. 在ItemsSource中,我有一个CompositeCollection,其中包含CollectionContainer和一行。 The Line is there just to prove to myself that I am drawing. The Line只是为了向自己证明我正在绘画。

I also have an object called "GraphPen" that contains a PathGeometry dependency property. 我还有一个名为“ GraphPen”的对象,其中包含PathGeometry依赖项属性。 The CollectionContainer of the user control contains an ObservableCollection of these GraphPens. 用户控件的CollectionContainer包含这些GraphPens的ObservableCollection。

Now, I have a "MainWindow" to test the user control. 现在,我有一个“ MainWindow”来测试用户控件。 In the MainWindow I have a DispatchTimer and in the Tick event of that timer, I add LineSegments to a PathFigure which has been added to the Figures collection of the PathGeometry of the single instance of the GraphPen. 在MainWindow中,我有一个DispatchTimer,在该计时器的Tick事件中,我向LineFigure添加LineSegments,该PathFigure已添加到GraphPen单个实例的PathGeometry的Figures集合中。

I expect to see a diagonal line being drawn in parallel to the existing red line, but nothing shows up. 我希望看到一条与现有的红线平行绘制的对角线,但是什么都没有显示。 If I put a break point at the end of the Tick event handler, I can examine the user control and drill down and see that the line segments do exist. 如果在Tick事件处理程序的末尾放置一个断点,则可以检查用户控件并向下钻取,看是否存在线段。 For some reason they are not being rendered. 由于某些原因,它们没有被渲染。 I suspect I have done something wrong in the binding. 我怀疑我在装订中做错了什么。

I will supply the code below. 我将在下面提供代码。

GraphPen.cs GraphPen.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;

namespace WpfExampleControlLibrary
{
    public class GraphPen : DependencyObject
    {
        #region Constructor

        public GraphPen()
        {
            PenGeometry = new PathGeometry();
        }

        #endregion Constructor

        #region Dependency Properties

        // Line Color

        public static PropertyMetadata PenLineColorPropertyMetadata
            = new PropertyMetadata(null);
        public static DependencyProperty PenLineColorProperty
            = DependencyProperty.Register(
                "PenLineColor",
                typeof(Brush),
                typeof(GraphPen),
                PenLineColorPropertyMetadata);
        public Brush PenLineColor
        {
            get { return (Brush)GetValue(PenLineColorProperty); }
            set { SetValue(PenLineColorProperty, value); }
        }

        // Line Thickness

        public static PropertyMetadata PenLineThicknessPropertyMetadata
            = new PropertyMetadata(null);
        public static DependencyProperty PenLineThicknessProperty
            = DependencyProperty.Register(
                "PenLineThickness",
                typeof(Int32),
                typeof(GraphPen),
                PenLineThicknessPropertyMetadata);
        public Int32 PenLineThickness
        {
            get { return (Int32)GetValue(PenLineThicknessProperty); }
            set { SetValue(PenLineThicknessProperty, value); }
        }

        // Pen Geometry

        public static PropertyMetadata PenGeometryMetadata = new PropertyMetadata(null);
        public static DependencyProperty PenGeometryProperty
            = DependencyProperty.Register(
                "PenGeometry",
                typeof(PathGeometry),
                typeof(UserControl1),
                PenGeometryMetadata);

        public PathGeometry PenGeometry
        {
            get { return (PathGeometry)GetValue(PenGeometryProperty); }
            set { SetValue(PenGeometryProperty, value); }
        }

        #endregion Dependency Properties
    }
}

UserControl1.xaml UserControl1.xaml

<UserControl Name="ExampleControl"
             x:Class="WpfExampleControlLibrary.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfExampleControlLibrary"
             DataContext="{Binding RelativeSource={RelativeSource Self}}"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>

        <DataTemplate DataType="{x:Type local:GraphPen}">
            <Path Stroke="{Binding Path=PenLineColor}"
                  StrokeThickness="{Binding Path=PenLineThickness}"
                  Data="{Binding Path=Geometry}">
            </Path>
        </DataTemplate>

    </UserControl.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="40"/>
        </Grid.RowDefinitions>
        <ItemsControl Grid.Column="0" Grid.Row="0">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas Background="Aquamarine">
                        <Canvas.LayoutTransform>
                            <ScaleTransform ScaleX="1" ScaleY="-1" CenterX=".5" CenterY=".5"/>
                        </Canvas.LayoutTransform>
                    </Canvas>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemsSource>
                <CompositeCollection>
                    <CollectionContainer
                        Collection="{
                            Binding Source={RelativeSource Self}, 
                            Path=GraphPens,
                            Mode=OneWay}"/>
                    <Line X1="10" Y1="0" X2="200" Y2="180" Stroke="DarkRed" StrokeThickness="2"/>
                </CompositeCollection>
            </ItemsControl.ItemsSource>
        </ItemsControl>
        <TextBox x:Name="debug" Grid.Column="0" Grid.Row="1" Text="{Binding Path=DebugText}"/>
    </Grid>
</UserControl>

UserControl1.xaml.cs UserControl1.xaml.cs

namespace WpfExampleControlLibrary
{
    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();

            GraphPens = new ObservableCollection<GraphPen>();
        }

        #region Dependency Properties

        // Pens

        public static PropertyMetadata GraphPenMetadata = new PropertyMetadata(null);
        public static DependencyProperty GraphPensProperty
            = DependencyProperty.Register(
                "GraphPens",
                typeof(ObservableCollection<GraphPen>),
                typeof(UserControl1),
                GraphPenMetadata);

        public ObservableCollection<GraphPen> GraphPens
        {
            get { return (ObservableCollection<GraphPen>)GetValue(GraphPensProperty); }
            set { SetValue(GraphPensProperty, value); }
        }

        // Debug Text

        public static PropertyMetadata DebugTextMetadata = new PropertyMetadata(null);
        public static DependencyProperty DebugTextProperty
            = DependencyProperty.Register(
                "DebugText",
                typeof(string),
                typeof(UserControl1),
                DebugTextMetadata);

        public string DebugText
        {
            get { return (string)GetValue(DebugTextProperty); }
            set { SetValue(DebugTextProperty, value); }
        }

        #endregion Dependency Properties
    }
}

MainWindow.xaml MainWindow.xaml

<Window x:Class="POC_WPF_UserControlExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:Exmpl="clr-namespace:WpfExampleControlLibrary;assembly=WpfExampleControlLibrary"
        xmlns:local="clr-namespace:POC_WPF_UserControlExample"
        mc:Ignorable="d"
        Title="MainWindow" Height="550" Width="550">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition />
            <ColumnDefinition Width="100"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="100" />
            <RowDefinition />
            <RowDefinition Height="100" />
        </Grid.RowDefinitions>
        <Exmpl:UserControl1 Grid.Column="1" Grid.Row="1" x:Name="myExample"/>
    </Grid>
</Window>

MainWindow.xaml.cs MainWindow.xaml.cs

namespace POC_WPF_UserControlExample
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private DispatcherTimer _timer = null;
        private GraphPen _graphPen0 = null;
        private Int32 _pos = 0;
        private PathFigure _pathFigure = null;

        public MainWindow()
        {
            InitializeComponent();

            _graphPen0 = new GraphPen();
            _graphPen0.PenLineColor = Brushes.DarkGoldenrod;
            _graphPen0.PenLineThickness = 2;
            myExample.GraphPens.Add(_graphPen0);

            _timer = new DispatcherTimer();
            _timer.Tick += Timer_Tick;
            _timer.Interval = new TimeSpan(0, 0, 0, 0, 100);
            _timer.Start();
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            _pos++;
            Point penPoint0 = new Point(_pos, _pos + 20);
            if (_graphPen0.PenGeometry.Figures.Count == 0)
            {
                _pathFigure = new PathFigure();
                _graphPen0.PenGeometry.Figures.Add(_pathFigure);
                _pathFigure.StartPoint = penPoint0;
            }
            else
            {
                LineSegment segment = new LineSegment(penPoint0, false);
                _pathFigure.Segments.Add(segment);
            }
            myExample.DebugText = _pos.ToString();
        }
    }
}

Screen Shot 屏幕截图

绘制的线应与红线平行

I did not need INotifyPropertyChanged , and I did not need to recreate PenGeometry . 我不需要INotifyPropertyChanged ,也不需要重新创建PenGeometry I'm sorry I wasted your time with those ideas. 对不起,我在这些想法上浪费了您的时间。

I've got your code drawing... something. 我有您的代码绘图...某样东西。 A line that grows. 增长的线。 I don't know if it's drawing exactly what you want, but you can figure out that part now that you can see what it is drawing. 我不知道它是否在绘制您想要的东西,但是现在您可以弄清楚那部分,现在您可以看到它绘制什么。

First, minor copy/paste error in GraphPen.cs : 首先, GraphPen.cs次要复制/粘贴错误:

    public static DependencyProperty PenGeometryProperty
        = DependencyProperty.Register(
            "PenGeometry",
            typeof(PathGeometry),
            typeof(UserControl1),
            PenGeometryMetadata);

Owner type parameter needs to be GraphPen , not UserControl1 : 所有者类型参数必须是GraphPen ,而不是UserControl1

            typeof(PathGeometry),
            typeof(GraphPen),
            PenGeometryMetadata);

Second: Binding in UserControl1 . 第二:在UserControl1绑定。 Your binding to Self isn't going to work because Self , in that case, is the CollectionContainer you're binding on. 您与Self绑定将无法正常工作,因为在这种情况下, Self是您要绑定的CollectionContainer Usually you'd use a source of RelativeSource={RelativeSource AncestorType=UserControl} , but CollectionContainer is not in the visual tree so that doesn't work (real intuitive, huh?). 通常,您将使用RelativeSource={RelativeSource AncestorType=UserControl} ,但是CollectionContainer不在可视树中,因此不起作用(真正直观,是吗?)。 Instead we use a BindingProxy (source to follow): 相反,我们使用BindingProxy (遵循源代码):

<UserControl.Resources>
    <!-- ... stuff ... -->

    <local:BindingProxy 
        x:Key="UserControlBindingProxy"
        Data="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}" 
        />
</UserControl.Resources>

And for the collection container... 对于收集容器...

<CollectionContainer
    Collection="{
        Binding 
        Source={StaticResource UserControlBindingProxy},
        Path=Data.GraphPens,
        Mode=OneWay}"
    />

Notice we're binding to Data.GraphPens ; 注意我们正在绑定到Data.GraphPens Data is the target of the proxy. Data是代理的目标。

Also, we need an ItemTemplate for the ItemsControl , because it doesn't know how to display a GraphPen : 另外,我们需要ItemsControlItemTemplate ,因为它不知道如何显示GraphPen

<ItemsControl.ItemTemplate>
    <DataTemplate DataType="local:GraphPen">
        <Border >
            <Path
                Data="{Binding PenGeometry}"
                StrokeThickness="{Binding PenLineThickness}"
                Stroke="{Binding PenLineColor, PresentationTraceSources.TraceLevel=None}"
                />
        </Border>
    </DataTemplate>
</ItemsControl.ItemTemplate>

Note PresentationTraceSources.TraceLevel=None . 注意PresentationTraceSources.TraceLevel=None Change None to High and it'll give you a lot of debugging info about the Binding in the VS Output pane. None更改为High ,它将在VS Output窗格中为您提供有关Binding的大量调试信息。 I added that when I was trying to figure out why I was setting PenLineColor to Brushes.Black in the constructor, but it kept coming out DarkGoldenrod at runtime. 我补充说,当我试图弄清楚为什么在构造函数PenLineColor设置为Brushes.Black时,但是在运行时它DarkGoldenrod出现DarkGoldenrod Can you say duhhh? 你能说对吗? Duhhh! h!

Now the binding proxy. 现在是绑定代理。 What that does is you take any random object you want to use as a DataContext , bind it to Data on a BindingProxy instance defined as a resource, and you've got that DataContext available via a resource that you can get to with a StaticResource . 这样做是将您要用作DataContext任何随机对象,将其绑定到定义为资源的BindingProxy实例上的Data ,并且已经通过可通过StaticResource获得的资源获得了DataContext If you're someplace where you can't get to something via the visual tree with RelativeSource , it's an option that you can rely on. 如果您在某个地方无法通过带有RelativeSource的可视树来获得某些东西,那么可以依靠它。

BindingProxy.cs 绑定代理

using System.Windows;

namespace WpfExampleControlLibrary
{
    public class BindingProxy : Freezable
    {
        #region Overrides of Freezable

        protected override Freezable CreateInstanceCore()
        {
            return new BindingProxy();
        }

        #endregion

        public object Data
        {
            get { return (object)GetValue(DataProperty); }
            set { SetValue(DataProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DataProperty =
            DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
    }
}

And finally, in MainWindow, you need to pass true for isStroked on the LineSegment instances: 最后,在MainWindow中,您需要在LineSegment实例上为isStroked传递true

LineSegment segment = new LineSegment(penPoint0, true);

Otherwise they're not drawn. 否则,它们不会被绘制。

So now it's back in your lap, in warm goldenrod and soothing aquamarine. 因此,现在又回到您的腿上,温暖的菊科植物和舒缓的海蓝宝石中。 Ave, imperator , and all that. Ave,imperator等。

Edit by original author! 由原作者编辑!

Thank you Ed for all your effort. 谢谢您Ed的所有努力。

  1. I can't believe I missed the UserControl1 -> GraphPen 我不敢相信我错过了UserControl1-> GraphPen
  2. The BindingProxy will be very handy BindingProxy将非常方便
  3. The TraceLevel will also be handy, I had not used that before TraceLevel也将很方便,我之前从未使用过
  4. I also corrected the DebugText binding and now that works 我还纠正了DebugText绑定,现在可以正常工作了

    I never even noticed that! 我什至没有注意到!

  5. In the DataTemplate why did we need to wrap the Path in a Border? 在DataTemplate中,为什么我们需要将路径包装在边框中?

    We don't. 我们没有。 Before I got the Path showing, I added that to have something in the template that was guaranteed to be visible . 在显示Path之前,我补充说要确保模板中有一些东西是可见的。 It had a green border originally. 它最初有一个绿色边框。 I removed those attributes, but forgot to remove the Border itself. 我删除了这些属性,但忘记删除Border本身。

  6. If you look in my Timer_Tick you will note that now all I have to update is adding new segments. 如果您查看我的Timer_Tick,您会注意到现在我需要更新的只是添加新的细分。 Hopefully, this will help performance. 希望这将有助于性能。 Your opinion? 你的意见?

    No idea. 不知道。 I would actually put that segment adding code in GraphPen as AddSegment(Point pt) and AddSegment(float x, float y) => AddSegment(new Point(x,y)); 我实际上会将该段添加到GraphPen作为AddSegment(Point pt)AddSegment(float x, float y) => AddSegment(new Point(x,y)); overloads. 超载。 I have a great allergy to putting logic in event handlers. 我非常想在事件处理程序中放入逻辑。 The most I'll do is toss an if or a try/catch around a non-handler method that does the real work. 我最想做的是将一个iftry/catch抛到一个可以完成实际工作的非处理程序方法周围。 Then I'd write AddSegment(Point pt) both ways and benchmark one against the other. 然后,我AddSegment(Point pt)两种方式编写AddSegment(Point pt) ,并以另一种方式进行基准测试。

I will add my code for completeness: 为了完整性,我将添加我的代码:

UserControl1.xaml UserControl1.xaml

<UserControl Name="ExampleControl"
             x:Class="WpfExampleControlLibrary.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfExampleControlLibrary"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>

        <local:BindingProxy
            x:Key="UserControlBindingProxy"
            Data="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}"/>

        <DataTemplate DataType="{x:Type local:GraphPen}">
            <Border>
                <Path
                    Data="{Binding PenGeometry}"
                    StrokeThickness="{Binding PenLineThickness}"
                    Stroke="{Binding
                        PenLineColor,
                        PresentationTraceSources.TraceLevel=None}"
                    />
            </Border>
        </DataTemplate>

    </UserControl.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="40"/>
        </Grid.RowDefinitions>
        <ItemsControl Grid.Column="0" Grid.Row="0">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <Canvas Background="Aquamarine">
                        <Canvas.LayoutTransform>
                            <ScaleTransform ScaleX="1" ScaleY="-1" CenterX=".5" CenterY=".5"/>
                        </Canvas.LayoutTransform>
                    </Canvas>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemsSource>
                <CompositeCollection>
                    <CollectionContainer
                        Collection="{Binding
                            Source={StaticResource UserControlBindingProxy}, 
                            Path=Data.GraphPens,
                            Mode=OneWay}"/>
                    <Line X1="10" Y1="0" X2="200" Y2="180" Stroke="DarkRed" StrokeThickness="2"/>
                </CompositeCollection>
            </ItemsControl.ItemsSource>
        </ItemsControl>
        <TextBox
            x:Name="debug"
            Grid.Column="0" Grid.Row="1"
            Text="{Binding
                Source={StaticResource UserControlBindingProxy},
                Path=Data.DebugText,
                Mode=OneWay}"/>
    </Grid>
</UserControl>

UserControl1.xaml.cs UserControl1.xaml.cs

namespace WpfExampleControlLibrary
{
    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class UserControl1 : UserControl
    {
        #region Constructor

        public UserControl1()
        {
            InitializeComponent();

            GraphPens = new ObservableCollection<GraphPen>();
        }

        #endregion Constructor

        #region Public Methods

        #endregion Public Methods

        #region Dependency Properties

        // Pens

        public static PropertyMetadata GraphPenMetadata = new PropertyMetadata(null);
        public static DependencyProperty GraphPensProperty
            = DependencyProperty.Register(
                "GraphPens",
                typeof(ObservableCollection<GraphPen>),
                typeof(UserControl1),
                GraphPenMetadata);

        public ObservableCollection<GraphPen> GraphPens
        {
            get { return (ObservableCollection<GraphPen>)GetValue(GraphPensProperty); }
            set { SetValue(GraphPensProperty, value); }
        }

        // Debug Text

        public static PropertyMetadata DebugTextMetadata = new PropertyMetadata(null);
        public static DependencyProperty DebugTextProperty
            = DependencyProperty.Register(
                "DebugText",
                typeof(string),
                typeof(UserControl1),
                DebugTextMetadata);

        public string DebugText
        {
            get { return (string)GetValue(DebugTextProperty); }
            set { SetValue(DebugTextProperty, value); }
        }

        #endregion Dependency Properties
    }
}

GraphPen.cs GraphPen.cs

namespace WpfExampleControlLibrary
{
    public class GraphPen : DependencyObject
    {
        #region Constructor

        public GraphPen()
        {
            PenGeometry = new PathGeometry();
        }

        #endregion Constructor

        #region Dependency Properties

        // Line Color

        public static PropertyMetadata PenLineColorPropertyMetadata
            = new PropertyMetadata(null);
        public static DependencyProperty PenLineColorProperty
            = DependencyProperty.Register(
                "PenLineColor",
                typeof(Brush),
                typeof(GraphPen),
                PenLineColorPropertyMetadata);
        public Brush PenLineColor
        {
            get { return (Brush)GetValue(PenLineColorProperty); }
            set { SetValue(PenLineColorProperty, value); }
        }

        // Line Thickness

        public static PropertyMetadata PenLineThicknessPropertyMetadata
            = new PropertyMetadata(null);
        public static DependencyProperty PenLineThicknessProperty
            = DependencyProperty.Register(
                "PenLineThickness",
                typeof(Int32),
                typeof(GraphPen),
                PenLineThicknessPropertyMetadata);
        public Int32 PenLineThickness
        {
            get { return (Int32)GetValue(PenLineThicknessProperty); }
            set { SetValue(PenLineThicknessProperty, value); }
        }

        // Pen Geometry

        public static PropertyMetadata PenGeometryMetadata = new PropertyMetadata(null);
        public static DependencyProperty PenGeometryProperty
            = DependencyProperty.Register(
                "PenGeometry",
                typeof(PathGeometry),
                typeof(GraphPen),
                PenGeometryMetadata);

        public PathGeometry PenGeometry
        {
            get { return (PathGeometry)GetValue(PenGeometryProperty); }
            set { SetValue(PenGeometryProperty, value); }
        }

        #endregion Dependency Properties
    }
}

BindingProxy.cs 绑定代理

namespace WpfExampleControlLibrary
{
    public class BindingProxy : Freezable
    {
        #region Override Freezable Abstract Parts
        protected override Freezable CreateInstanceCore()
        {
            return new BindingProxy();
        }

        #endregion Override Freezable Abstract Parts

        #region Dependency Properties

        // Using a DependencyProperty as the backing store for Data.
        // This enables animation, styling, binding, etc...
        public static PropertyMetadata DataMetadata = new PropertyMetadata(null);
        public static readonly DependencyProperty DataProperty
            = DependencyProperty.Register(
                "Data",
                typeof(object),
                typeof(BindingProxy),
                DataMetadata);

        public object Data
        {
            get { return (object)GetValue(DataProperty); }
            set { SetValue(DataProperty, value); }
        }

        #endregion Dependency Properties
    }
}

MainWindow.xaml MainWindow.xaml

<Window x:Class="POC_WPF_UserControlExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:Exmpl="clr-namespace:WpfExampleControlLibrary;assembly=WpfExampleControlLibrary"
        xmlns:local="clr-namespace:POC_WPF_UserControlExample"
        mc:Ignorable="d"
        Title="MainWindow" Height="550" Width="550">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition />
            <ColumnDefinition Width="100"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="100" />
            <RowDefinition />
            <RowDefinition Height="100" />
        </Grid.RowDefinitions>
        <Exmpl:UserControl1 Grid.Column="1" Grid.Row="1" x:Name="myExample"/>
    </Grid>
</Window>

MainWindow.xaml.cs MainWindow.xaml.cs

namespace POC_WPF_UserControlExample
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private DispatcherTimer _timer = null;
        private GraphPen _graphPen0 = null;
        private Int32 _pos = 0;
        private PathFigure _pathFigure0 = null;
        private bool _firstTime = true;

        public MainWindow()
        {
            InitializeComponent();

            _pathFigure0 = new PathFigure();
            _graphPen0 = new GraphPen();
            _graphPen0.PenLineColor = Brushes.DarkGoldenrod;
            _graphPen0.PenLineThickness = 2;
            _graphPen0.PenGeometry = new PathGeometry();
            _graphPen0.PenGeometry.Figures.Add(_pathFigure0);
            myExample.GraphPens.Add(_graphPen0);

            _timer = new DispatcherTimer();
            _timer.Tick += Timer_Tick;
            _timer.Interval = new TimeSpan(0, 0, 0, 0, 100);
            _timer.Start();
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            _pos++;
            Point penPoint0 = new Point(_pos, _pos + 20);
            if (_firstTime)
            {
                myExample.GraphPens[0].PenGeometry.Figures[0].StartPoint = penPoint0;
                _firstTime = false;
            }
            else
            {
                LineSegment segment = new LineSegment(penPoint0, true);
                myExample.GraphPens[0].PenGeometry.Figures[0].Segments.Add(segment);
            }

            myExample.DebugText = _pos.ToString();
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM