28

I have a WPF form which basically looks like this:

<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>

The overlay grid hides everything else (i.e. the "normal content") and is only shown under special circumstances (i.e. if the network connection goes down). This works perfectly fine when running the program.

Now, in design mode, the problem is that Visual Studio ignores the Visibility="Hidden". Usually, this makes perfect sense (after all, I want to be able to edit the hidden UI elements), but in my case it's annoying, because it prevents me from editing the stuff in the DockPanel in the designer.

So, what I'd like to do is something like that:

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

But, alas, there is no such property, or at least none that I know of. Any ideas?

Heinzi
  • 167,459
  • 57
  • 363
  • 519
  • 1
    I'm going about a solution in a different way in that I'm trying to figure out how the TabControl achieves this. With the TabControl you can set a specific tab to be selected but within the designer it will ignore this if you place your cursor within the code for one of the tabs or on the actual tabs in the designer and instead show the design-time selected tab. I think the Popup control should work the same way and I'm working on something similar to the Silverlight ChildWindow control that will give me this type of design time behavior. – jpierson Jun 24 '11 at 14:32

8 Answers8

79

Starting from VS2012 you can just use the Blend namespace IsHidden attribute:

  • add if not already present xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  • put d:IsHidden="true" on element you want to hide at design time only
adospace
  • 1,841
  • 1
  • 17
  • 15
  • 2
    Doesn't work in conjunction with the Visibility attribute. Visibility seems to have priority. And I guess there's no d:Visibility :( – Edgar Jan 25 '17 at 19:45
  • 2
    Cool! In VS2017 the blend xmlns is already there, but this solution still did not work ("Property 'IsHidden' does not exist in blend..."). I have to search for another info and found out, that after the line containing **xmlns:d="http://schemas.microsoft.com/expression/blend/2008"** you need to include two other lines: **xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"** Then the IsHidden attribute works prefectly. (Sorry, formatting is limited here) – Vit Kovalcik Sep 23 '17 at 06:39
  • 1
    In VS2017, with the said xmlns added, IntelliSense does not 'see' the d:IsHidden attribute, but adding it works exactly as described in this answer. – Andrei Pana Jan 30 '19 at 16:25
  • 1
    @VitKovalcik `xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"`, your `http://` missing. – huang Jun 03 '21 at 03:00
11

Nice solution, I was having a similar problem and I agree that there are cases where it's needed. Here is a minor update that allows you to edit the value to turn IsHidden on and off while designing. I also applied a ScaleTransform instead of setting Width and Height to reduce screen artifacts a bit if control grips etc are displayed and to avoid conflicts if the control being hidden already has Width and Height properties set (assuming that the control doesn't already have a LayoutTransform set on it).

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 
Jay13
  • 860
  • 9
  • 15
9

Nice work! I translated to C# and change the property it's changing to 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;
    }
}
gregsdennis
  • 7,218
  • 3
  • 38
  • 71
8

Since there is no built-in way to do this, I decided to implement a solution myself, which was surprisingly easy to do using attached properties:

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

After declaring a namespace, the feature can be used like this:

<Grid ... local:DesignModeTool.IsHidden="True">
[stuff I don't want to be shown in the designer]
</Grid>
Heinzi
  • 167,459
  • 57
  • 363
  • 519
3

Other than not using the designer (really, consider this) you could separate the contents of the Grid into a separate UserControl. That way, you could just update that UserControl in isolation from the visibility logic.

Kent Boogaart
  • 175,602
  • 35
  • 392
  • 393
  • 1
    About using the designer: Yes, I know what you mean. I only use the designer for navigation (click on a control and the editor jumps to the XAML code). This, however, is a very essential feature for large XAML files. – Heinzi Sep 02 '09 at 16:19
2

I am on the other side... hate VS 2012 for hiding hidden WPF controls in designer. I need to see them so i have modified gregsdennis code to:

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" will show the control in designer mode.

drongal
  • 21
  • 1
2

I ran into a similar problem recently.

I am using a Rectangle to obscure the main window during a modal dialog's execution. I have the Visibility data bound, but the Rectangle made the designer unusable. I mad the Z index a one time data bind, and a fallback value was lower than the window I wanted to obscure. When the application starts up, the Rectangle's Z index is bound to a higher value than the window.

mittio
  • 346
  • 5
  • 6
1

Probably it will be useful for someone else. If you want to hide element in designer mode in VS2022:

d:Visibility="Hidden"