WPF:为自定义 UIElement 数据绑定 PointCollection

发布于 2024-10-04 23:49:04 字数 2651 浏览 5 评论 0原文

我正在尝试制作一个 WPF UIElement 来执行一些特殊的渲染。

问题是我无法让数据绑定适用于 PointCollection。在 GraphElementOnRender() 内部,Points 属性为 null,这对我来说没有任何意义。

class GraphElement : UIElement
{
    public static readonly DependencyProperty PointsProperty = DependencyProperty.Register(
        "Points",
        typeof(PointCollection),
        typeof(GraphElement),
        new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));            

    public PointCollection Points
    {
        get { return (PointCollection)GetValue(PointsProperty); }
        set { SetValue(PointsProperty, value); }
    }

    protected override void OnRender(DrawingContext drawingContext)
    {
        base.OnRender(drawingContext);

        //Points is null
        Debug.Assert(Points != null);
    }

}

class TestViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private PointCollection _viewModelPoints;
    public PointCollection ViewModelPoints
    {
        get { return _viewModelPoints; }
        set
        {
            _viewModelPoints = value;
            if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("ViewModelPoints"));
        }
    }
}

<Window x:Class="TestApp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestApp"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Canvas>
        <local:GraphElement Points="{Binding Path=ViewModelPoints}"/>
    </Canvas>
</Grid>


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using 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;

namespace TestApp
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            var testViewModel = new TestViewModel();
            testViewModel.ViewModelPoints = new PointCollection();
            testViewModel.ViewModelPoints.Add(new Point(0.0, 0.0));
            DataContext = testViewModel;
            InitializeComponent();
        }
    }
}

I'm trying to make a WPF UIElement that does some special rendering.

The problem is that I can't get databinding to work for a PointCollection. Inside OnRender() of the GraphElement, the Points property is null, which doesn't make any sense to me.

class GraphElement : UIElement
{
    public static readonly DependencyProperty PointsProperty = DependencyProperty.Register(
        "Points",
        typeof(PointCollection),
        typeof(GraphElement),
        new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));            

    public PointCollection Points
    {
        get { return (PointCollection)GetValue(PointsProperty); }
        set { SetValue(PointsProperty, value); }
    }

    protected override void OnRender(DrawingContext drawingContext)
    {
        base.OnRender(drawingContext);

        //Points is null
        Debug.Assert(Points != null);
    }

}

class TestViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private PointCollection _viewModelPoints;
    public PointCollection ViewModelPoints
    {
        get { return _viewModelPoints; }
        set
        {
            _viewModelPoints = value;
            if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("ViewModelPoints"));
        }
    }
}

<Window x:Class="TestApp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:TestApp"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Canvas>
        <local:GraphElement Points="{Binding Path=ViewModelPoints}"/>
    </Canvas>
</Grid>


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using 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;

namespace TestApp
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            var testViewModel = new TestViewModel();
            testViewModel.ViewModelPoints = new PointCollection();
            testViewModel.ViewModelPoints.Add(new Point(0.0, 0.0));
            DataContext = testViewModel;
            InitializeComponent();
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

伤感在游骋 2024-10-11 23:49:04

GraphElement 的继承从 UIElement 更改为 FrameworkElement(后者又继承 UIElement)。这是您拥有 DataContext dp 等的位置。

class GraphElement : FrameworkElement
{
    //...
}

将代码复制到示例项目中(将 UIElement 更改为 FrameworkElement),并且 OnRender 中的 Points 不为空。在此处上传了项目。

Change the inheritance on GraphElement from UIElement to FrameworkElement (which in turn inherits UIElement). This is where you have the DataContext dp etc.

class GraphElement : FrameworkElement
{
    //...
}

Copied your code into a sample project (changing UIElement to FrameworkElement) and Points is not null in OnRender. Uploaded the project here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文