呈现模板时WPF正在等待消息
在我的遗留项目中,我有一个treeview和一个绑定在treeview叶子上的OnClick事件。基本上,每次选择叶时,我都会获得节点类型,并将模板应用到控件中,例如:呈现模板时WPF正在等待消息,wpf,treeview,datatemplate,Wpf,Treeview,Datatemplate,在我的遗留项目中,我有一个treeview和一个绑定在treeview叶子上的OnClick事件。基本上,每次选择叶时,我都会获得节点类型,并将模板应用到控件中,例如: gridDati.Template = Resources["tmplBit"] as ControlTemplate; “tmplBit”是一个具有多个列的数据模板。所有这些都很好,但有时当我有20列和30/40条记录时,应用所选模板需要时间(4/5秒)。 我想显示一条等待的消息,或类似的东西,但我找不到如何显示。我已经有一
gridDati.Template = Resources["tmplBit"] as ControlTemplate;
“tmplBit”是一个具有多个列的数据模板。所有这些都很好,但有时当我有20列和30/40条记录时,应用所选模板需要时间(4/5秒)。
我想显示一条等待的消息,或类似的东西,但我找不到如何显示。我已经有一个显示等待消息的窗口,我尝试将其用作:
var aboutBox = new winWaitingMessage(Global.LM.T("@_3261_Inizio export"));
aboutBox.Show();
// Template?
gridDati.Template = Resources["tmplBit"] as ControlTemplate;
aboutBox.Close();
但是框会立即关闭,因此我找不到一个事件来告诉我何时应用和呈现模板。任何提示?框架不提供此类事件,但您可以处理模板中某个元素的
加载事件,并在发生此事件时关闭窗口,例如:
gridDati.Template = Resources["tmplBit"] as ControlTemplate;
gridDati.ApplyTemplate();
FrameworkElement fe = gridDati.Template.FindName("YourElement", gridDati) as FrameworkElement;
if (fe == null)
{
aboutBox.Close();
}
else
{
void Fe_Loaded(object sender, RoutedEventArgs e)
{
aboutBox.Close();
fe.Loaded -= Fe_Loaded;
}
fe.Loaded += Fe_Loaded;
}
XAML:
<ControlTemplate x:Key="tmplBit">
...
<Button x:Name="YourElement" ... />
您可以使用任务
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr FindWindow(IntPtr hwnd, string title);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int PostMessage(IntPtr hwnd, int msg, uint wParam, uint lParam);
public const int WM_CLOSE = 0x10;
public const int WM_KEYDOWN = 0x0100;
public const int WM_KEYUP = 0x0101;
public const int VK_RETURN = 0x0D;
private void Button_Click(object sender, RoutedEventArgs e)
{
Task task1 = new Task(() =>
{
gridDati.Template = Resources["tmplBit"] as ControlTemplate;
});
task1.Start();
Task cwt = task1.ContinueWith(t=>
{
FindAndKillWindow("Warning");
});
MessageBox.Show("Waiting...", "Warning");
}
private static void FindAndKillWindow(string title)
{
IntPtr ptr = FindWindow(IntPtr.Zero, title);
if (ptr != IntPtr.Zero)
{
int ret = PostMessage(ptr, WM_CLOSE, 0, 0);
ptr = FindWindow(IntPtr.Zero, title);
if (ptr != IntPtr.Zero)
{
PostMessage(ptr, WM_KEYDOWN, VK_RETURN, 0);
PostMessage(ptr, WM_KEYUP, VK_RETURN, 0);
}
}
}
嗯,听起来很奇怪,你怎么能在if中声明一个方法?@Spaccaspecchi:它被称为一个局部函数,是在C#7.0中引入的:我明白了,但我仍然在使用.NET 4。5@Spaccaspecchi:您仍然可以使用C#7.0。或者干脆不使用局部函数,而是使用lambda表达式。请参见“我的编辑”以获取示例。@Spaccaspecchi:如果您的问题已经解决,请记住接受答案并投票表决。它不起作用,消息框在整个数据网格渲染之前被杀死。我仍在努力寻找一个事件,它让我有机会完全呈现我的控制权
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr FindWindow(IntPtr hwnd, string title);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int PostMessage(IntPtr hwnd, int msg, uint wParam, uint lParam);
public const int WM_CLOSE = 0x10;
public const int WM_KEYDOWN = 0x0100;
public const int WM_KEYUP = 0x0101;
public const int VK_RETURN = 0x0D;
private void Button_Click(object sender, RoutedEventArgs e)
{
Task task1 = new Task(() =>
{
gridDati.Template = Resources["tmplBit"] as ControlTemplate;
});
task1.Start();
Task cwt = task1.ContinueWith(t=>
{
FindAndKillWindow("Warning");
});
MessageBox.Show("Waiting...", "Warning");
}
private static void FindAndKillWindow(string title)
{
IntPtr ptr = FindWindow(IntPtr.Zero, title);
if (ptr != IntPtr.Zero)
{
int ret = PostMessage(ptr, WM_CLOSE, 0, 0);
ptr = FindWindow(IntPtr.Zero, title);
if (ptr != IntPtr.Zero)
{
PostMessage(ptr, WM_KEYDOWN, VK_RETURN, 0);
PostMessage(ptr, WM_KEYUP, VK_RETURN, 0);
}
}
}