隐藏Visual Studio设计器中的WPF元素

时间:2009-08-24 13:44:49

标签: wpf visual-studio-2008

我有一个WPF表单,基本上是这样的:

<Window ...>
  <Grid>
    <DockPanel>
      [content shown during normal operation]
    </DockPanel>

    <Grid Background="#CCCC" Visibility="Hidden">
      [overlay grid which is only shown during special circumstances]
    </Grid>
  </Grid>
</Window>

覆盖网格隐藏其他所有内容(即“正常内容”),并且仅在特殊情况下显示(即,如果网络连接断开)。当运行程序时,这非常适用。

现在,在设计模式中,问题是Visual Studio忽略了Visibility="Hidden"。通常,这是完全合理的(毕竟,我希望能够编辑隐藏的UI元素),但在我的情况下,它很烦人,因为它阻止我编辑设计器中DockPanel中的东西。

所以,我想做的是这样的事情:

<Grid Background="#CCCC" Visibility="Hidden" VS.ShowInDesigner="False">
  [overlay grid which is only shown during special circumstances]
</Grid>

但是,唉,没有这样的财产,或者至少没有我知道的财产。有什么想法吗?

7 个答案:

答案 0 :(得分:65)

从VS2012开始,您只需使用Blend命名空间IsHidden属性:

  • 添加(如果尚未存在)xmlns:d =“http://schemas.microsoft.com/expression/blend/2008”
  • 在您想要在设计时隐藏的元素上添加d:IsHidden =“true”

答案 1 :(得分:11)

很好的解决方案,我遇到了类似的问题,我同意有些情况需要它。这是一个次要更新,允许您编辑值以在设计时打开和关闭IsHidden。如果显示控件夹点等,我还应用了ScaleTransform而不是设置Width和Height来减少屏幕伪像,并且如果隐藏的控件已经设置了Width和Height属性,则避免冲突(假设控件还没有在它上面设置LayoutTransform)。

Public Class DesignModeTool

  Public Shared ReadOnly IsHiddenProperty As DependencyProperty = DependencyProperty.RegisterAttached( _
    "IsHidden", GetType(Boolean), GetType(DesignModeTool), _
    New FrameworkPropertyMetadata(False, New PropertyChangedCallback(AddressOf OnIsHiddenChanged)))

  Public Shared Sub SetIsHidden(ByVal element As FrameworkElement, ByVal value As Boolean)
    element.SetValue(IsHiddenProperty, value)
  End Sub

  Public Shared Function GetIsHidden(ByVal element As FrameworkElement) As Boolean
    Return DirectCast(element.GetValue(IsHiddenProperty), Boolean)
  End Function

  Private Shared Sub OnIsHiddenChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
    If System.ComponentModel.DesignerProperties.GetIsInDesignMode(d) AndAlso True.Equals(e.NewValue) Then
      With DirectCast(d, FrameworkElement)
        .LayoutTransform = New ScaleTransform(0.001, 0.001)
      End With
    ElseIf System.ComponentModel.DesignerProperties.GetIsInDesignMode(d) AndAlso False.Equals(e.NewValue) Then
      With DirectCast(d, FrameworkElement)
        .LayoutTransform = Nothing
      End With
    End If
  End Sub
End Class 

答案 2 :(得分:8)

干得好!我翻译成C#并将其更改的属性更改为RenderTransform。

static class DesignModeTool
{
    public static readonly DependencyProperty IsHiddenProperty =
        DependencyProperty.RegisterAttached("IsHidden",
            typeof(bool),
            typeof(DesignModeTool),
            new FrameworkPropertyMetadata(false,
                new PropertyChangedCallback(OnIsHiddenChanged)));

    public static void SetIsHidden(FrameworkElement element, bool value)
    {
        element.SetValue(IsHiddenProperty, value);
    }

    public static bool GetIsHidden(FrameworkElement element)
    {
        return (bool)element.GetValue(IsHiddenProperty);
    }

    private static void OnIsHiddenChanged(DependencyObject d,
                                          DependencyPropertyChangedEventArgs e)
    {
        if (!DesignerProperties.GetIsInDesignMode(d)) return;
        var element = (FrameworkElement)d;
        element.RenderTransform = (bool)e.NewValue
           ? new ScaleTransform(0, 0)
           : null;
    }
}

答案 3 :(得分:7)

由于没有内置方法可以做到这一点,我决定自己实现一个解决方案,使用附加属性非常容易:

Public Class DesignModeTool
    Public Shared ReadOnly IsHiddenProperty As DependencyProperty = DependencyProperty.RegisterAttached( _
        "IsHidden", GetType(Boolean), GetType(DesignModeTool), _
        New FrameworkPropertyMetadata(False, New PropertyChangedCallback(AddressOf OnIsHiddenChanged)))

    Public Shared Sub SetIsHidden(ByVal element As UIElement, ByVal value As Boolean)
        element.SetValue(IsHiddenProperty, value)
    End Sub

    Public Shared Function GetIsHidden(ByVal element As UIElement) As Boolean
        Return DirectCast(element.GetValue(IsHiddenProperty), Boolean)
    End Function

    Private Shared Sub OnIsHiddenChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
        If System.ComponentModel.DesignerProperties.GetIsInDesignMode(d) AndAlso True.Equals(e.NewValue) Then
            With DirectCast(d, FrameworkElement)
                .Width = 0
                .Height = 0
            End With
        End If
    End Sub
End Class

声明命名空间后,可以像这样使用该功能:

<Grid ... local:DesignModeTool.IsHidden="True">
[stuff I don't want to be shown in the designer]
</Grid>

答案 4 :(得分:3)

除了不使用设计器(实际上,请考虑这一点)之外,您可以将Grid的内容分成单独的UserControl。这样,您可以直接从可见性逻辑更新UserControl

答案 5 :(得分:2)

我最近遇到了类似的问题。

在模式对话框的执行过程中,我使用Rectangle来遮盖主窗口。我绑定了Visibility数据,但Rectangle使设计器无法使用。我疯狂的Z索引一次数据绑定,后退值低于我想隐藏的窗口。当应用程序启动时,Rectangle的Z索引绑定到比窗口更高的值。

答案 6 :(得分:1)

我在另一边...讨厌VS 2012隐藏设计中隐藏的WPF控件。我需要看到它们,所以我修改了gregsdennis代码:

public class DesignModeTool
{
    public static readonly DependencyProperty IsHiddenProperty = DependencyProperty.RegisterAttached("IsHidden",   typeof(bool),  typeof(DesignModeTool),   new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnIsHiddenChanged)));

    public static void SetIsHidden(FrameworkElement element, bool value)
    {
        element.SetValue(IsHiddenProperty, value);
    }

    public static bool GetIsHidden(FrameworkElement element)
    {
        return (bool)element.GetValue(IsHiddenProperty);
    }

    private static void OnIsHiddenChanged(DependencyObject d,
                                          DependencyPropertyChangedEventArgs e)
    {
        if (!DesignerProperties.GetIsInDesignMode(d)) return;
        var element = (FrameworkElement)d;
        element.Visibility=Visibility.Visible;

    }
}

wpfClasses2:DesignModeTool.IsHidden =“False”将以设计师模式显示控件。