Скрыть элементы WPF в конструкторе Visual Studio - PullRequest
25 голосов
/ 24 августа 2009

У меня есть форма 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". Обычно это имеет смысл (в конце концов, я хочу иметь возможность редактировать скрытые элементы пользовательского интерфейса), но в моем случае это раздражает, потому что мешает мне редактировать вещи в DockPanel в конструкторе.

Итак, я хотел бы сделать что-то вроде этого:

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

Но, увы, такого свойства нет или, по крайней мере, нет, о котором я знаю. Есть идеи?

Ответы [ 7 ]

65 голосов
/ 22 января 2014

Начиная с VS2012, вы можете просто использовать атрибут IsHidden пространства имен Blend:

  • добавить, если еще нет xmlns: d = "http://schemas.microsoft.com/expression/blend/2008"
  • положить d: IsHidden = "true" для элемента, который вы хотите скрыть только во время разработки
11 голосов
/ 04 февраля 2010

Хорошее решение, у меня была похожая проблема, и я согласен, что есть случаи, когда это необходимо. Вот небольшое обновление, которое позволяет вам редактировать значение, чтобы включать и выключать IsHidden во время проектирования. Я также применил ScaleTransform вместо установки ширины и высоты, чтобы немного уменьшить артефакты на экране, если отображаются ручки управления и т. Д., И чтобы избежать конфликтов, если скрытый элемент управления уже имеет свойства ширины и высоты (при условии, что элемент управления еще не имеет 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 
8 голосов
/ 14 июня 2012

Отличная работа! Я перевел на 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;
    }
}
7 голосов
/ 02 сентября 2009

Поскольку для этого не существует встроенного способа, я решил сам реализовать решение, которое было удивительно легко сделать с помощью прикрепленных свойств:

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>
3 голосов
/ 24 августа 2009

Если не использовать дизайнер (действительно, учтите это), вы можете разделить содержимое Grid на отдельный UserControl. Таким образом, вы можете просто обновить это UserControl отдельно от логики видимости.

2 голосов
/ 30 сентября 2010

Недавно я столкнулся с подобной проблемой.

Я использую Прямоугольник, чтобы скрыть главное окно во время выполнения модального диалога. У меня есть привязанные данные Visibility, но Rectangle сделал дизайнер непригодным для использования. Я сошла с ума по Z-индексу при однократном связывании данных, и значение возврата было ниже, чем окно, которое я хотел скрыть Когда приложение запускается, индекс Z прямоугольника привязывается к более высокому значению, чем окно.

1 голос
/ 02 января 2014

Я с другой стороны ... ненавижу 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" покажет элемент управления в режиме конструктора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...