Выберите сгенерированный во время выполнения куб в HelixViewport3D - PullRequest
0 голосов
/ 19 декабря 2018

Я использую Helix3DToolkit и пытаюсь сделать выборку для куба, который генерируется во время выполнения.Куб имеет тип SelectableCube, который является производным от UIElement3D.Если я просто добавляю куб во время инициализации MainWindow, все работает нормально, и я могу выбрать и отменить выбор куба по своему усмотрению.

См. Изображение приложения с выбранным кубом

Если куб добавлен в соответствии с настройками ползунков, он не может быть выбран и не реагирует на MouseOver и MouseLeave. Почему?

Кубы, сгенерированные в соответствии со значениями ползунка

Я знаю, что мог бы реализовать механизм тестирования попаданий, чтобы проверить, какой куб был выбран, но яНе понимаете, почему в этом случае не вызываются обработчики событий в классе 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>

...