WPF-依赖属性初始化



我正在尝试实现将图像投射到3D模型上的WPF组件。为了使其使用更整洁,我正在尝试使用依赖性属性,以便我可以以以下方式从我的视图上绑定控件:

<viewers:MyViewer
    ProjectedImageSource="{Binding ViewModel.ProjectedSource}"
    Visibility="{Binding Path=HueMapVisible, Converter={StaticResource booleanToVisibilityConverter}}"
    />

控件如下:

<UserControl x:Class="ImageProjector.Controls.Viewers.MyViewer"
             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" 
             mc:Ignorable="d"
             d:DesignHeight="300" d:DesignWidth="300">
    <LayoutGrid>
        <Viewport3D Name="Viewport" Grid.ColumnSpan="7" Grid.RowSpan="7" />
    </LayoutGrid>
</UserControl>

codebehind:

public interface IMyViewer { }
public partial class MyViewer : UserControl, IMyViewer
{
    private IImageModel3D imageModel3D;
    public MyViewer() : this(Ninjector.Get<IImageModel3D>()){ }
    public MyViewer(IImageModel3D imageModel3D)
    {
        this.InitializeComponent();
        this.ProjectedImageSource.Changed += ProjectedImageSource_Changed;
    }
    private void ProjectedImageSource_Changed(object sender, EventArgs e)
    {
        imageModel3D.SetImage((BitmapImage)sender);
    }
    public static readonly DependencyProperty ProjectedImageSourceProperty = DependencyProperty.Register(
                                                                    "ProjectedImageSource",
                                                                    typeof(BitmapSource),
                                                                    typeof(MyViewer));
    public BitmapSource ProjectedImageSource
    {
        get => (BitmapSource)this.GetValue(ProjectedImageSourceProperty);
        set => this.SetValue(ProjectedImageSourceProperty, value);
    }
}

我遇到的问题是,在构造函数中调用ProjectEdimagesource是无效的(我也在已加载的回调中尝试过(,所以我无法设置更改的事件处理程序。

我知道有一个validateValue回调,但这必须是静态静态,因此在这种情况下不起作用。

我可以用一些技巧来使此功能起作用,还是从根本上有缺陷来尝试?

您应该在依赖属性元数据中注册一个属性ChangedCallback:

public static readonly DependencyProperty ProjectedImageSourceProperty =
    DependencyProperty.Register(
        nameof(ProjectedImageSource),
        typeof(BitmapSource),
        typeof(MyViewer),
        new PropertyMetadata(ProjectedImageSourceChanged));
private static void ProjectedImageSourceChanged(
    DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
    var viewer = (MyViewer)obj;
    viewer.imageModel3D.SetImage(e.NewValue as BitmapImage); // may not be a BitmapImage
}

或短:

public static readonly DependencyProperty ProjectedImageSourceProperty =
    DependencyProperty.Register(
        nameof(ProjectedImageSource),
        typeof(BitmapSource),
        typeof(MyViewer),
        new PropertyMetadata(
            (o, e) => ((MyViewer)o).imageModel3D.SetImage(e.NewValue as BitmapImage)));

注意,似乎不必要您的IImageModel3D.SetImage方法需要BitmapImage参数。更好地使用BitmapSource,然后以这样的方式编写您的属性ChangedCallback:

public static readonly DependencyProperty ProjectedImageSourceProperty =
    DependencyProperty.Register(
        nameof(ProjectedImageSource),
        typeof(BitmapSource),
        typeof(MyViewer),
        new PropertyMetadata(
            (o, e) => ((MyViewer)o).imageModel3D.SetImage((BitmapSource)e.NewValue)));

如果设定确实需要一个位图像,则应更改依赖项属性的类型。

最新更新