在WPF窗口中更改繁重的UserControl

时间:2015-11-06 14:30:58

标签: c# wpf optimization user-controls

关于如何替换WPF中显示的UserControl,我已经阅读了很多关于此事的主题。 建议倾向于数据绑定内容控制,Kent Boggart回答this question

无论如何,第一个问题是我的用户控件涉及繁重的图形显示,并且正在使用不能同时访问的公共资源。 我的意思是重型图形,在OtherControl上,有几个视频和一个3D模型,对动态事件作出反应。 BallControl有一个带有TranslateAnimation的椭圆,以及一个对事件做出反应的边距。我相信由于渲染页面的动态事件,整个项目有点沉重。

所以我的解决方案并不理想:我正在清除Grid中的内容,并将其替换为所需的用户控件(网格占据整个页面)。 与上述帖子的不同之处在于,我希望(如果可能的话)保持用户控制不变。

问题在于,这些控件需要经常切换,并且在 1或2小时后使用它时,此异常显示(代码中指定的行):

  

System.ArgumentException:指定的Visual已经是另一个Visual的子项或CompositionTarget类的根。

     

System.Windows.Threading.Dispatcher.Invoke(Action callback,DispatcherPriority priority,CancellationToken cancellationToken,TimeSpan timeout)

我的代码显然是错误的,我希望有一个更清洁的解决方案。更重要的是,我已经知道只有一个UI线程,并且预先加载已经构建的控件,然后才能进行二次拉伸。 更确切地说,一些代码非常受欢迎:

MainWindow.xaml

<Window x:Class="Testing.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Testing"
    xmlns:h="http://helix-toolkit.org/wpf"
    Title="MainWindow" Height="1080" Width="1920" WindowStartupLocation="CenterScreen" WindowStyle="None" MinHeight="1080" MinWidth="1920" ResizeMode="NoResize">
<Grid x:Name="Griddy">
</Grid>

MainWindow.xaml.cs

    BallControl _boule;
    OtherControl _otherControl;

    public MainWindow()
    {
        InitializeComponent();
        Mouse.OverrideCursor = Cursors.None;


        EventReceive.Subscribe(this);
        // Instanciate both UserControls
        _boule = new BallControl();
        _otherControl = new OtherControl();
        panelToDisplay = Turn.Ball;


        Griddy.Children.Add(boule);

    }

    /// <summary>
    /// Event coming from panels to notify which one is to be displayed
    /// returning value is an Enum
    /// </summary>
    public void Receive<T>(T arg) where T : EventArgs
    {
        var casted = arg as EventArriving;
        if (casted != null)
        {
            PanelToDisplay = casted.TurningTable;
        }
    }


    private Turn panelToDisplay;
    public Turn PanelToDisplay
    {
        get { return panelToDisplay; }
        set 
        {
            if (panelToDisplay != value)
            {
                panelToDisplay = value;
                if (panelToDisplay == Turn.Other)
                {
                    try
                    {
                        this.Griddy.Dispatcher.Invoke((Action)(() => Griddy.Children.Add(_otherControl))); //Where the exception shows up
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show(e.ToString());

                    }
                    try
                    {
                        this.Griddy.Dispatcher.Invoke((Action)(() => Griddy.Children.Remove(_boule)));
                    }
                    catch (Exception e)
                    {
                         MessageBox.Show(e.ToString());
                    }

                }
                if (panelToDisplay == Turn.Ball)
                {   // Bad Pattern where I remove a control to display another one.
                    try
                    {
                        this.Griddy.Dispatcher.Invoke((Action)(() => Griddy.Children.Add(_boule))); //Where the exception shows up
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show(e.ToString());
                    }
                    try
                    {
                        this.Griddy.Dispatcher.Invoke((Action)(() => Griddy.Children.Remove(_otherControl)));
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show(e.ToString());
                    }
                }
            }

        }
    }

总结一下:

  • 如何更换/更改/添加&amp;以干净的方式从MainWindow中删除用户控件?
  • 如果每次更改都不需要加载备份,即使控件图形化很重,我该如何看待它呢?

0 个答案:

没有答案