Скрыть элементы WPF в дизайнере Visual Studio
У меня есть форма 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>
Но, увы, такого имущества нет, или, по крайней мере, ни одного, о котором я знаю. Любые идеи?
Ответы
Ответ 1
Хорошее решение, у меня была аналогичная проблема, и я согласен, что есть случаи, когда это необходимо. Вот небольшое обновление, которое позволяет редактировать значение, чтобы включить и выключить IsHidden во время проектирования. Я также применял ScaleTransform вместо установки ширины и высоты, чтобы немного уменьшить артефакты экрана, если отображаются управляющие рукоятки и т.д., И избежать конфликтов, если уже скрытый элемент управления имеет свойства 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
Начиная с версии VS2012, вы можете просто использовать атрибут IsHidden пространства имен Blend:
- добавить, если еще нет xmlns: d = "http://schemas.microsoft.com/expression/blend/2008"
- put d: IsHidden = "true" для элемента, который вы хотите скрыть только во время разработки
Ответ 3
Поскольку для этого нет встроенного способа, я решил реализовать решение самостоятельно, что было удивительно легко сделать с помощью подключенных свойств:
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
Хорошая работа! Я перевел на С# и изменил свойство, которое он изменил на 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;
}
}
Ответ 5
Кроме использования конструктора (действительно, учтите это), вы можете разделить содержимое Grid
на отдельный UserControl
. Таким образом, вы можете просто обновить это UserControl
отдельно от логики видимости.
Ответ 6
Недавно я столкнулся с подобной проблемой.
Я использую Rectangle, чтобы затенять главное окно во время выполнения модального диалога. У меня есть данные о видимости, но Rectangle сделал конструктор непригодным. Я безумный индекс Z один раз привязывал данные, а запасное значение было меньше, чем окно, которое я хотел скрыть. Когда приложение запускается, индекс Rectangle Z привязан к более высокому значению, чем окно.
Ответ 7
Я на другой стороне... ненавижу 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" покажет элемент управления в режиме конструктора.
Ответ 8
Фактически drongal мне пришлось установить DesignModeTool.IsHidden = "TRUE", чтобы он показывал мои скрытые части моего UserControl.