我正在为Autodesk Revit开发一个加载项,我使用XAML和C#创建了一个WPF窗口,如图1所示。我的加载项的用户需要在我的Window和Revit之间切换,我的窗口需要保持其状态。由于它是模态对话框,因此在我的窗口打开之前,用户无法与Revit交互。所以,在这种情况下,我使用Hide而不是关闭窗口。当用户再次需要它时,加载项使用ShowDialog再次显示窗口。但问题是,当我再次显示窗口时,它显示为白色(没有可见的控件),如图像2所示。一旦我调整窗口大小,所有控件都会显示回来并且窗口开始正常工作。关于如何解决这个问题的任何想法?
public partial class NavigationWindow:Window,INotifyPropertyChanged { ... }
使用此代码显示,
NavigationWindow navigationWindow = new NavigationWindow();
navigationWindow.ShowDialog ();
隐藏窗口,我正在使用
Application.Current.Dispatcher.Invoke (() =>
{
this.Visibility = System.Windows.Visibility.Hidden;
});
答案 0 :(得分:0)
我建议改用无模式窗口。这是在与Revit交互时保持窗口正常的正确方法。解决此问题的方法是使用IdleEvent
或ExternalEvent
。这是一个带有空闲事件的简单场景。只需将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
});