隐藏

时间:2018-01-10 15:49:26

标签: c# wpf windows xaml revit

我正在为Autodesk Revit开发一个加载项,我使用XAML和C#创建了一个WPF窗口,如图1所示。我的加载项的用户需要在我的Window和Revit之间切换,我的窗口需要保持其状态。由于它是模态对话框,因此在我的窗口打开之前,用户无法与Revit交互。所以,在这种情况下,我使用Hide而不是关闭窗口。当用户再次需要它时,加载项使用ShowDialog再次显示窗口。但问题是,当我再次显示窗口时,它显示为白色(没有可见的控件),如图像2所示。一旦我调整窗口大小,所有控件都会显示回来并且窗口开始正常工作。关于如何解决这个问题的任何想法?

  1. https://i.stack.imgur.com/hjhrW.png
  2. https://imgur.com/a/msuc7

    public partial class NavigationWindow:Window,INotifyPropertyChanged { ... }

  3. 使用此代码显示,

    NavigationWindow navigationWindow = new NavigationWindow(); 
    navigationWindow.ShowDialog ();
    

    隐藏窗口,我正在使用

    Application.Current.Dispatcher.Invoke (() =>
    {
        this.Visibility = System.Windows.Visibility.Hidden;
    });
    

1 个答案:

答案 0 :(得分:0)

我建议改用无模式窗口。这是在与Revit交互时保持窗口正常的正确方法。解决此问题的方法是使用IdleEventExternalEvent。这是一个带有空闲事件的简单场景。只需将window.ShowDialog()切换为window.Show()即可使其无模式。

首先,你需要向IExternalApplication添加一个空闲事件队列和处理程序,所以像这样:

public class AppCommand : IExternalApplication
{
    private static Queue<Action<UIApplication>> Tasks;
    public Result OnStartup(UIControlledApplication application)
    {
        Tasks = new Queue<Action<UIApplication>>();
        application.Idling += OnIdling;

        return Result.Succeeded;
    }
    private static void OnIdling(object sender, IdlingEventArgs e)
    {
        var app = (UIApplication)sender;
        lock (Tasks)
        {
            if (Tasks.Count <= 0) return;

            var task = Tasks.Dequeue();
            task(app);
        }
    }
    public static void EnqueueTask(Action<UIApplication> task)
    {
        lock (Tasks)
        {
            Tasks.Enqueue(task);
        }
    }
}

因此,当Revit没有做任何事情时,Idling事件将会触发。这是从另一个线程(UI)与Revit交互的最佳时机。因此,当您处于无模式对话框并希望将任务发送到Revit时,您可以使用EnquuqTask实用程序将任务放入队列中,然后在不忙的情况下Revit将触发空闲事件,使任务出列并执行它。这可以保证您不会在Revit的范围之外执行任何操作,并且可以让窗口保持无模式状态,以便在窗口打开时与Revit进行交互。

以下是如何将任务从任何地方添加到队列中:

EnqueueTask(app =>
{
    //do something
    //use app object to interact with Revit
});