【问题标题】:Hide WPF elements in Visual Studio designer在 Visual Studio 设计器中隐藏 WPF 元素
【发布时间】:2010-11-22 07:01:00
【问题描述】:

我有一个基本上如下所示的 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>

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

【问题讨论】:

  • 我正在以不同的方式提出一个解决方案,因为我试图弄清楚 TabControl 是如何实现这一点的。使用 TabControl,您可以设置要选择的特定选项卡,但在设计器中,如果您将光标放在其中一个选项卡的代码中或设计器中的实际选项卡上,它将忽略这一点,而是显示设计时选定的选项卡.我认为 Popup 控件应该以相同的方式工作,并且我正在研究类似于 Silverlight ChildWindow 控件的东西,它将给我这种类型的设计时行为。

标签: wpf visual-studio-2008


【解决方案1】:

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

  • 如果不存在,则添加 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  • 仅在设计时将 d:IsHidden="true" 放在要隐藏的元素上

【讨论】:

  • 不能与 Visibility 属性结合使用。可见性似乎具有优先权。而且我猜没有 d:Visibility :(
  • 酷!在 VS2017 中,混合 xmlns 已经存在,但此解决方案仍然不起作用(“混合中不存在属性 'IsHidden'...”)。我必须搜索另一个信息并发现,在包含 xmlns:d="schemas.microsoft.com/expression/blend/2008" 的行之后,您需要包含另外两行:xmlns:mc="@987654322 @" mc:Ignorable="d" 然后 IsHidden 属性可以正常工作。 (抱歉,这里的格式有限)
  • 在 VS2017 中,添加了上述 xmlns 后,IntelliSense 不会“看到” d:IsHidden 属性,但添加它的工作原理与此答案中的描述完全相同。
  • @VitKovalcik xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006",你的http:// 不见了。
【解决方案2】:

很好的解决方案,我遇到了类似的问题,我同意在某些情况下需要它。这是一个小更新,允许您在设计时编辑值以打开和关闭 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 

【讨论】:

  • 这很有帮助。我喜欢这样的代码,我可以在那里学习。谢谢。
【解决方案3】:

干得好!我翻译成 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;
    }
}

【讨论】:

    【解决方案4】:

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

    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>
    

    【讨论】:

    • 这很有帮助。谢谢。
    【解决方案5】:

    除了不使用设计器(真的,考虑一下)之外,您还可以将Grid 的内容分离为单独的UserControl。这样一来,您就可以在与可见性逻辑隔离的情况下更新 UserControl

    【讨论】:

    • 关于使用设计师:是的,我知道你的意思。我只使用设计器进行导航(单击控件,编辑器跳转到 XAML 代码)。然而,这对于大型 XAML 文件来说是一项非常重要的功能。
    【解决方案6】:

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

    在模态对话框执行期间,我使用 Rectangle 来遮挡主窗口。我绑定了 Visibility 数据,但 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" 将以设计器模式显示控件。

      【讨论】:

        猜你喜欢
        • 2015-09-15
        • 1970-01-01
        • 1970-01-01
        • 2011-12-20
        • 2014-08-31
        • 1970-01-01
        • 2012-02-15
        • 1970-01-01
        • 2011-05-04
        相关资源
        最近更新 更多