在HelixViewport3D中选择运行时生成的多维数据集

时间:2018-12-19 10:35:28

标签: c# wpf helix-3d-toolkit

我正在使用Helix3DToolkit,并且试图在运行时生成的多维数据集上进行选择。该多维数据集的类型是SelectableCube,它是从UIElement3D派生的。 如果我只是在MainWindow的初始化过程中添加一个多维数据集,则一切正常,可以根据需要选择和取消选择该多维数据集。

See an image of the application with a selected cube

如果根据滑块的设置添加了多维数据集,则无法选择该多维数据集,并且它不会对MouseOver和MouseLeave做出反应。 为什么?

Cubes generated according to slider values

我知道我可以实现一个命中测试机制来检查已选择哪个多维数据集,但是我不明白为什么在这种情况下为什么不调用SelectableCube类中的事件处理程序?与工作案例有何不同?

到目前为止,我的代码:

public class SelectableCube : UIElement3D
{
    public Point3D Center
    {
        get { return (Point3D)GetValue(CenterProperty); }
        set { SetValue(CenterProperty, value);
        }
    }

    // Using a DependencyProperty as the backing store for Center.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty CenterProperty =
        DependencyProperty.Register("Center", typeof(Point3D), typeof(SelectableCube),new PropertyMetadata(CenterChangeCallback));

    private static void CenterChangeCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((SelectableCube)d).SetCurrentValue(CenterProperty, (Point3D)e.NewValue);
        MeshBuilder builder = new MeshBuilder();
        builder.AddBox(((SelectableCube)d).Center, 1, 1, 1);
        GeometryModel3D model = new GeometryModel3D(builder.ToMesh(), MaterialHelper.CreateMaterial(new SolidColorBrush(Color.FromRgb(255, 0, 0))));
        ((SelectableCube)d).Visual3DModel = model;
    }

    public SelectableCube()
    {
    }

    protected override void OnMouseEnter(MouseEventArgs e)
    {
        base.OnMouseEnter(e);
        GeometryModel3D g = Visual3DModel as GeometryModel3D;
        if (!g.Material.Equals(Materials.Gold))
        {
            g.Material = Materials.Gray;
        }
        e.Handled = true;
    }

    protected override void OnMouseLeave(MouseEventArgs e)
    {
        base.OnMouseLeave(e);
        GeometryModel3D g = Visual3DModel as GeometryModel3D;

        if (!g.Material.Equals(Materials.Gold))
        {
            g.Material = Materials.LightGray;
        }
        e.Handled = true;
    }

    protected override void OnMouseDown(MouseButtonEventArgs e)
    {
        base.OnMouseDown(e);
        GeometryModel3D g = Visual3DModel as GeometryModel3D;
        if (g.Material.Equals(Materials.Gold))
        {
            g.Material = Materials.Gray;
        }
        else
        {
            g.Material = Materials.Gold;
        }
        e.Handled = true;
    }
}

//

public partial class MainWindow : Window
{

    public Visual3DCollection Cubes { get; set; }

    public MainWindow()
    {
        InitializeComponent();
        this.MainViewport.MouseDown += MainViewport_MouseDown;
        ContainerUIElement3D col = this.MainViewport.Children.FirstOrDefault(x => x.GetType().Equals(typeof(ContainerUIElement3D))) as ContainerUIElement3D;
        ModelVisual3D cubeContainer = col.Children[0] as ModelVisual3D;
        Cubes = cubeContainer.Children;
        Cubes.Add(new SelectableCube() { Center = new Point3D(1,1,1)});
    }

    private void MainViewport_MouseDown(object sender, MouseButtonEventArgs e)
    {
        Point pointerLocation = e.GetPosition(this.MainViewport);
        HitTestResult res = VisualTreeHelper.HitTest(this.MainViewport, pointerLocation);
    }

    private void ColSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    { 
        Redraw();
    }

    private void RowSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
        Redraw();
    }

    private void Redraw()
    {
        Cubes.Clear();
        for (int row = 1; row <= this.RowSlider.Value; row++)
        {
            for (int col = 1; col <= this.ColSlider.Value; col++)
            {
                SelectableCube c = new SelectableCube() { Center = new Point3D(row + (row - 1) * this.DistanceSlider.Value, col + (col - 1) + this.DistanceSlider.Value, 5) };
                Cubes.Add(c);
            }
        }

    }
}

XAML代码:

<Window x:Class="HelixTest.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:HelixToolkit="clr-namespace:HelixToolkit.Wpf;assembly=HelixToolkit.Wpf"
    xmlns:local="clr-namespace:HelixTest"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>

    <Grid.RowDefinitions>
        <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <HelixToolkit:HelixViewport3D Grid.Column="0" ZoomExtentsWhenLoaded="True" Name="MainViewport">
        <HelixToolkit:SunLight/>
        <ContainerUIElement3D>
            <ModelVisual3D/>
        </ContainerUIElement3D>
        <HelixToolkit:GridLinesVisual3D Width="8" Length="8" MinorDistance="1" MajorDistance="1" Thickness="0.01"/>
    </HelixToolkit:HelixViewport3D>
    <StackPanel Grid.Column="1" Orientation="Vertical">
        <StackPanel Orientation="Horizontal">
            <Label Content="# Columns:"/>
            <Slider Name="ColSlider" Width="120" Maximum="100" 
                    TickFrequency="1" IsSnapToTickEnabled="True"
                    ValueChanged="ColSlider_ValueChanged"></Slider>
            <Label Content="{Binding ElementName=ColSlider, Path=Value}"></Label>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <Label Content="# Rows:"/>
            <Slider Name="RowSlider" Width="120" Maximum="100" 
                    TickFrequency="1" IsSnapToTickEnabled="True"
                    ValueChanged="RowSlider_ValueChanged"></Slider>
            <Label Content="{Binding ElementName=RowSlider, Path=Value}"></Label>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <Label Content="# Distance:"/>
            <Slider Name="DistanceSlider" Width="120" Maximum="2" 
                    TickFrequency="0.1" IsSnapToTickEnabled="True"
                    ValueChanged="DistanceSlider_ValueChanged"></Slider>
            <Label Content="{Binding ElementName=DistanceSlider, Path=Value}"></Label>
        </StackPanel>
    </StackPanel>
</Grid>

0 个答案:

没有答案