自定义控件无法正确显示

时间:2016-12-21 17:32:22

标签: c# wpf

我正在尝试开发一个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>

任何人都知道我做错了什么?

1 个答案:

答案 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);
        }
    }
}