首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Helix工具的WPF,在尝试更新PropertyChangedEventHandler视图时,ModelVisual3D总是为空。

使用Helix工具的WPF,在尝试更新PropertyChangedEventHandler视图时,ModelVisual3D总是为空。
EN

Stack Overflow用户
提问于 2021-10-11 11:39:17
回答 1查看 196关注 0票数 1

我是新的WPF和我有问题,试图更新主窗口用户界面后,改变。

我有下面的MainWindow.xaml (我将展示其中的一部分,因为它很大)

代码语言:javascript
复制
<Window
    x:Class="SimpleDemo.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:HelixToolkit="clr-namespace:HelixToolkit.Wpf;assembly=HelixToolkit.Wpf"
    xmlns:local="clr-namespace:SimpleDemo"
    Title="Plot 3D data"
    Width="680"
    Height="680" WindowStartupLocation="CenterScreen">
    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>

下一个重要部分是MainWindow的3D绘图部分,在这里,我将绘图的内容绑定到名为Model的Model3D对象中。

代码语言:javascript
复制
            <!--  Remember to add light to the scene  -->
            <HelixToolkit:SunLight />

            <!--  The content of this visual is defined in MainViewModel.cs  -->
            <ModelVisual3D Content="{Binding Path = Model, Mode=OneWayToSource,NotifyOnTargetUpdated=True, UpdateSourceTrigger=PropertyChanged}" />

            <!--  You can also add elements here in the xaml  -->
            <HelixToolkit:GridLinesVisual3D
                Width="800"
                Length="800"
                MajorDistance="15"
                MinorDistance="15"
                Thickness="0.05" />

        </HelixToolkit:HelixViewport3D>
        <StackPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal">
            <Button Margin="5" Click="Backward_Click">Backward</Button>
            <Button Margin="5" Click="Forward_Click">Forward</Button>
        </StackPanel>

该程序的思想是从txt文件中读取前500个数据点(x、y、z),然后使用Helix创建一个AddRectangularMesh()。我这样做是针对多个点集,最后有一个带有多个AddRectangularMesh()对象的网格。之后,我将向HelixViewport3D显示最终结果。在UI中,我有两个向前和向后的按钮。前进按钮试图从txt文件中画出下500个点。

在我的MainWindow.xaml.cs文件中,我调用按钮的事件处理程序,该按钮调用MainViewModel.cs文件中的函数,其中计算了该数据点的所有函数,最后的结果将保存在Model3D模型对象上,然后必须在UI上绘制。

按钮调用Forward_click事件并增加计数器以读取下一个数据点。

<Button Margin="5" Click="Forward_Click">Forward</Button>

按下按钮后,事件处理程序将被调用,但它是空的,因此UI永远不会更新,也无法显示下一个数据点。在我的代码中,我实现了事件处理程序,以侦听模型的更改,因此在函数执行之后,模型对象将被更新,然后调用处理程序来更新UI。

MainViewModel类定义为:

代码语言:javascript
复制
    public class MainViewModel : Window, INotifyPropertyChanged

和事件处理程序如下:

代码语言:javascript
复制
        private Model3D model;
        public Model3D Model 
        { 
            get { return model; }
            set 
            {
                model = value;
                OnPropertyChanged(nameof(Model));
            } 
        }

        protected void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
                handler(this, e);
        }

        protected void OnPropertyChanged(string propertyName)
        {
            OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
        }

我在代码中放置断点,当我按下按钮时,将调用处理程序,但为null,然后不更新或不做任何操作,该函数使用新的点计算新的Model3D对象,但不绘制新的结果。

如果我在public MainViewModel()部分运行相同的函数,就会显示前500个点,但这是由于窗口的第一次运行造成的。

这就是在按下每个按钮之后如何更新Model对象的方式。

代码语言:javascript
复制
public void CoreCalculations()
        {
            for (int i = 0 ; i < 500; i++)
            {
                //read File Line
                // --- Do something with the points ---
                // create a mesh using the points and AddRectangularMesh
            }
            MeshGeometry3D mesh = meshBuilder.ToMesh(true);
            Material blueMaterial = MaterialHelper.CreateMaterial(Colors.Blue);
            modelGroup.Children.Add(new GeometryModel3D { Geometry = mesh, Transform = new TranslateTransform3D(2, 0, 0), Material = blueMaterial, BackMaterial = blueMaterial });
            Model = modelGroup;
        }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-11 11:52:28

尝试将OneWayToSource更改为OneWay。来自文档

当目标属性更改时更新源属性。

你可能会想用相反的方法。每当模型更改时更新目标。

MainViewModel是从Window继承的,这有点奇怪。我建议看一看helix3D "SimpleDemo“。为了确认更改模型是否有效,让mainViewModel继承INotifyPropertyChanged,并添加以下代码:

代码语言:javascript
复制
        private async Task RemoveModel()
        {
            await Task.Delay(5000);
            Model = null;
            OnPropertyChanged(nameof(Model));
        }
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

并在构造函数中调用RemoveModel。这将使模型在5s之后被移除。请注意,示例代码适用于调试,而不是其他任何东西。

您还应该能够使用活视觉树资源管理器来帮助调试UI。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69525602

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档