也许标题措辞错误。
我有一个“全局”忙碌指示器,只要我在ChildWindow打开时不尝试使用它就会很好。
我在App.xaml.cs中使用静态方法访问“全局”忙指标:
BusyIndicator b = (BusyIndicator)App.Current.RootVisual;
if (b != null)
{
b.BusyContent = busyText;
b.IsBusy = true;
}
但是,如果ChildWindow打开,BusyIndicator总是在它后面。
我以为我可以设置b.Content = VisualTreeHelper.GetOpenPopups().First()
,但这也不起作用。
有没有人有关于在打开的ChildWindows上使用BusyIndicator的任何提示?
提前致谢。
更新(解决方案)
戴夫S派我走上正轨。它比我希望的更复杂,但这是我的解决方案。首先,我必须为ChildWindow制作一个完整的样式,复制所有的模板样式(留下一些出于后尺寸的原因):
<Style x:Key="MyChildWindowStyle" TargetType="gs:MyChildWindow">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="gs:MyChildWindow">
<toolkit:BusyIndicator IsBusy="{TemplateBinding IsBusy}" BusyContent="{TemplateBinding BusyContent}" BusyContentTemplate="{StaticResource MyBusyIndicatorDataTemplate}">
<Grid>
<ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</toolkit:BusyIndicator>
</Style>
然后,我创建了我的基类;注意构造函数设置样式。 (如果我试图将其抽象化,就会出现错误。)
public class MyChildWindow : ChildWindow
{
public static readonly DependencyProperty IsBusyProperty = DependencyProperty.Register("IsBusy", typeof(bool), typeof(MyChildWindow), null);
public static readonly DependencyProperty BusyContentProperty = DependencyProperty.Register("BusyContent", typeof(object), typeof(MyChildWindow), null);
public bool IsBusy
{
get { return (bool)GetValue(IsBusyProperty); }
set { SetValue(IsBusyProperty, value); }
}
public object BusyContent
{
get { return GetValue(BusyContentProperty); }
set { SetValue(BusyContentProperty, value); }
}
public MyChildWindow()
{
this.Style = Application.Current.Resources["MyChildWindowStyle"] as Style;
}
}
确保添加一个新的ChildWindow,并将&lt; controls:ChildWindow更改为&lt; gs:MyChildWindow(与代码隐藏相同)。
最后,更新静态SetBusyIndicator方法:
public static void SetBusyIndicator(string busyText, Uri busyImage)
{
var op = VisualTreeHelper.GetOpenPopups().Where(o => o.Child is MyChildWindow);
if (op.Any())
{
var bidc = new MyBusyIndicatorDataContext(busyText, busyImage);
foreach (System.Windows.Controls.Primitives.Popup p in op)
{
var c = p.Child as MyChildWindow;
c.BusyContent = bidc;
c.IsBusy = true;
}
}
else
{
BusyIndicator b = Current.RootVisual as BusyIndicator;
if (b != null)
{
b.BusyContent = new MyBusyIndicatorDataContext(busyText, busyImage);
b.IsBusy = true;
}
}
}
我不确定这是最有效的,但它看起来效果很好。
答案 0 :(得分:3)
当您将应用程序根视觉集设置为繁忙的微调器时,您将无法更改Z-Index,因此它高于ChildWindow。你最好的选择是扩展ChildWindow控件并在其中添加一个繁忙的微调器,然后在打开窗口时在ChildWindow上设置IsBusy而不是root视觉。
希望有所帮助。
答案 1 :(得分:1)
您不必将ChildWindow子类化为能够在ChildWindows上使用BusyIndicator。 我正在使用以下解决方案:
1 - 为所有ChildWindow控件定义全局ContentTemplate。将IsBusy属性绑定到ChildWindow的datacontext的“IsBusy”。
<Style TargetType="sdk:ChildWindow">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<toolkit:BusyIndicator IsBusy="{Binding IsBusy}">
<ContentPresenter Content="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</toolkit:BusyIndicator>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
2-定义在silverlight应用程序运行期间准备就绪的单例类。我为此选择了App类。实现INotifyPropertyChanged接口以自动刷新所有IsBusy绑定器。实现IsBusy属性。实现ShowBusyIndicator和HideBusyIndicator方法。在ShowBusyIndicator方法中迭代所有打开的ChildWindows并更新它们的DataContexts。
public class App : Application, INotifyPropertyChanged
{
public static BusyIndicator GlobalBusyIndicator { get; private set; }
private bool _isBusy;
public bool IsBusy
{
get
{
return _isBusy;
}
set
{
_isBusy = value;
RaisePropertyChanged(new PropertyChangedEventArgs("IsBusy"));
}
}
public static void ShowBusyIndicator()
{
var popups = VisualTreeHelper.GetOpenPopups();
foreach (var p in popups)
{
ChildWindow cw = p.Child as ChildWindow;
if (cw != null)
cw.DataContext = App.Current;
}
(Current as App).IsBusy = true;
GlobalBusyIndicator.IsBusy = true;
}
public static void HideBusyIndicator()
{
(Current as App).IsBusy = false;
GlobalBusyIndicator.IsBusy = false;
}
private void Application_Startup(object sender, StartupEventArgs e)
{
string baseurl = Host.Source.AbsoluteUri;
BaseUrl = baseurl.Substring(0, baseurl.IndexOf("ClientBin"));
GlobalBusyIndicator = new BusyIndicator();
GlobalBusyIndicator.HorizontalAlignment = HorizontalAlignment.Stretch;
GlobalBusyIndicator.VerticalAlignment = VerticalAlignment.Stretch;
GlobalBusyIndicator.Content = new Shell();
this.RootVisual = GlobalBusyIndicator;
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(PropertyChangedEventArgs e)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, e);
}
}