我正在使用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>