我正在尝试开发一个WPF自定义控件,可用于覆盖其他控件,有效地将它们调暗,以便明确它们不可用。这类似于您在许多网站上看到的效果,当显示弹出窗口时,它们会使背景页面变灰。
麻烦的是,当它运行时,它们不再显示所包含的控件,而是消失。我将在下面展示代码,以及非常简单的示例用法。
这是控件本身的代码(名称空间和省略用来节省一些空间)......
public class OverlayDisableControl : UserControl {
protected override void OnInitialized(EventArgs e) {
base.OnInitialized(e);
VerticalAlignment = VerticalAlignment.Stretch;
HorizontalAlignment = HorizontalAlignment.Stretch;
Grid grid = new Grid();
ContentPresenter content = new ContentPresenter {
Name = "content",
Content = Content
};
grid.Children.Add(content);
Grid overlay = new Grid {
Name = "Overlay",
Visibility = Visibility.Collapsed
};
Border background = new Border {
Name = "background",
VerticalAlignment = VerticalAlignment.Stretch,
HorizontalAlignment = HorizontalAlignment.Stretch,
Background = new SolidColorBrush(Colors.LightGray),
Opacity = .6
};
overlay.Children.Add(background);
grid.Children.Add(overlay);
Content = grid;
}
public static readonly DependencyProperty OverlayVisibleProperty =
DependencyProperty.Register("OverlayVisible", typeof(bool),
typeof(OverlayDisableControl),
new FrameworkPropertyMetadata(SetOverlayVisibleStatic));
public bool OverlayVisible {
get {
return (bool) GetValue(OverlayVisibleProperty);
}
set {
SetValue(OverlayVisibleProperty, value);
}
}
private static void SetOverlayVisibleStatic(DependencyObject d, DependencyPropertyChangedEventArgs e) {
(d as OverlayDisableControl).SetOverlayVisible(d as OverlayDisableControl, (bool) e.NewValue);
}
private void SetOverlayVisible(OverlayDisableControl odc, bool visible) {
if (visible) {
DoubleAnimation anim = new DoubleAnimation {
From = 0,
To = 1, // Visible
Duration = new Duration(TimeSpan.FromMilliseconds(350)),
EasingFunction = new QuadraticEase {
EasingMode = EasingMode.EaseInOut
}
};
odc.Visibility = Visibility.Visible;
odc.BeginAnimation(OpacityProperty, anim);
} else {
DoubleAnimation anim = new DoubleAnimation {
From = 1,
To = 0, // Invisible
Duration = new Duration(TimeSpan.FromMilliseconds(350)),
EasingFunction = new QuadraticEase {
EasingMode = EasingMode.EaseInOut
}
};
anim.Completed += (s1, e1) => {
odc.Visibility = Visibility.Collapsed;
};
odc.BeginAnimation(OpacityProperty, anim);
}
}
}
...这是一个示例用法。这就是你所需要的,没有代码隐藏,只需将其放到窗口即可。 GroupBox中的控件只是用于测试......
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<CheckBox Content="Show?"
Margin="3"
Name="ShowChk"
IsChecked="True" />
</StackPanel>
<local:OverlayDisableControl OverlayVisible="{Binding ElementName=ShowChk, Path=IsChecked, Mode=TwoWay}"
Grid.Row="1">
<GroupBox Header="Gratuitous controls"
Margin="3">
<StackPanel Orientation="Vertical">
<TextBlock Text="This is some text"
Margin="3" />
<TextBox Margin="3" />
<Button Content="Save"
Margin="3" />
</StackPanel>
</GroupBox>
</local:OverlayDisableControl>
</Grid>
任何人都知道我做错了什么?
答案 0 :(得分:1)
您可以动画/更改UserControl
本身的可见性,同时它是您之后的Grid overlay
。
您的代码更改:
public class OverlayDisableControl : UserControl
{
private Grid overlay = new Grid
{
Name = "Overlay",
Visibility = Visibility.Collapsed
};
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
...
//Grid overlay = new Grid
//{
// Name = "Overlay",
// Visibility = Visibility.Collapsed
//};
...
}
...
private static void SetOverlayVisibleStatic(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as OverlayDisableControl).SetOverlayVisible((bool)e.NewValue);
}
private void SetOverlayVisible(bool visible)
{
if (visible)
{
DoubleAnimation anim = new DoubleAnimation
{
...
};
overlay.Visibility = Visibility.Visible;
overlay.BeginAnimation(OpacityProperty, anim);
}
else
{
DoubleAnimation anim = new DoubleAnimation
{
...
};
anim.Completed += (s1, e1) => {
overlay.Visibility = Visibility.Collapsed;
};
overlay.BeginAnimation(OpacityProperty, anim);
}
}
}