简体   繁体   English

WPF属性面板类似于Visual Studio的

[英]WPF Properties Panel similar to Visual Studio's

Just wondering is their any examples or elements which can look very similar to the Properties panel used in Visual Studio? 只是想知道他们的任何示例或元素看起来与Visual Studio中使用的“属性”面板非常相似? My guess the one in Visual Studio 2010 is built upon WPF, almost definitely a treeview? 我猜Visual Studio 2010中的那个基于WPF,几乎肯定是树视图?

If you want to use some simple XAML, the following is visually identical to the WinForms PropertyGrid but is much easier to work with: 如果您想使用一些简单的XAML,以下内容在视觉上与WinForms PropertyGrid完全相同,但更容易使用:

<Style x:Key="InnerBorder" TargetType="{x:Type Border}">
  <Setter Property="BorderThickness" Value="1" />
  <Setter Property="Margin" Value="4" />
  <Setter Property="BorderBrush" Value="#B4B0A8" />
</Style>

<Grid>

  <Grid.RowDefinitions>
    <RowDefinition />
    <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>

  <!-- Main property grid area -->
  <Border Style="{StaticResource InnerBorder}">
    <ListBox
      ItemsSource="{Binding Parameters}"
      IsSynchronizedWithCurrentItem="True"
      KeyboardNavigation.TabNavigation="Continue"
      HorizontalContentAlignment="Stretch" BorderThickness="0">

      <!-- Category grouping rows -->
      <ListBox.GroupStyle>
        <GroupStyle>
          <GroupStyle.HeaderTemplate>
            <DataTemplate>
              <TextBlock Text="{Binding Name}" Background="#D4D0C8" FontWeight="Bold" Padding="2 2 0 4" Margin="0 0 0 3"/>
            </DataTemplate>
          </GroupStyle.HeaderTemplate>
          <GroupStyle.ContainerStyle>
            <Style>
              <Setter Property="Control.Margin" Value="0 0 0 8" />
            </Style>
          </GroupStyle.ContainerStyle>
        </GroupStyle>
      </ListBox.GroupStyle>

      <!-- Item container style -->
      <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
          <Setter Property="Focusable" Value="False" />
          <Setter Property="TabIndex" Value="0" />
          <Setter Property="Template">
            <Setter.Value>
              <ControlTemplate TargetType="{x:Type ListBoxItem}">

                <DockPanel Margin="4 0 0 0" IsKeyboardFocusWithinChanged="DockPanel_IsKeyboardFocusWithinChanged" MouseDown="DockPanel_MouseDown">
                  <TextBlock Name="TitleBlock" Text="{Binding DisplayName}" Width="135" />
                  <ContentPresenter />
                </DockPanel>

                <ControlTemplate.Triggers>
                  <Trigger Property="IsSelected" Value="true">
                    <Setter TargetName="TitleBlock" Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
                    <Setter TargetName="TitleBlock" Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
                  </Trigger>
                </ControlTemplate.Triggers>

              </ControlTemplate>
            </Setter.Value>
          </Setter>
        </Style>
      </ListBox.ItemContainerStyle>

    </ListBox>
  </Border>

  <!-- Help area -->
  <Border Style="{StaticResource InnerBorder}" Grid.Row="1" DataContext="{Binding Parameters}">
    <StackPanel HorizontalAlignment="Stretch" Margin="2">
      <TextBlock FontWeight="Bold" Text="{Binding /DisplayName}" />
      <TextBlock Text="{Binding /Description}" TextWrapping="Wrap" />
    </StackPanel>
  </Border>

</Grid>

And here is the code behind 这是背后的代码

private void DockPanel_IsKeyboardFocusWithinChanged(object sender, DependencyPropertyChangedEventArgs e)
{
  var element = (FrameworkElement)sender;
  if(element.IsKeyboardFocusWithin)
  {
    Visual cur = element;
    while(cur!=null && !(cur is ListBoxItem))
      cur = (Visual)VisualTreeHelper.GetParent(cur);
    ((ListBoxItem)cur).IsSelected = true;
  }
}

private void DockPanel_MouseDown(object sender, MouseEventArgs e)
{
  ((FrameworkElement)sender).MoveFocus(new TraversalRequest(FocusNavigationDirection.First));
}

private void InitializeView()
{
  var view = CollectionViewSource.GetDefaultView(Parameters);
  if(view.GroupDescriptions.Count==0)
    view.GroupDescriptions.Add(new PropertyGroupDescription("Category"));

  if(view.SortDescriptions.Count==0)
  {
    view.SortDescriptions.Add(new SortDescription("Category", ListSortDirection.Ascending));
    view.SortDescriptions.Add(new SortDescription("DisplayName", ListSortDirection.Ascending));
  }
}

The reason this property grid is nicer to work with in WPF is that you can add any kind of object to the Parameters collection as long as it has a Category, DisplayName, and Description. 此属性网格在WPF中更好用的原因是,只要具有Category,DisplayName和Description,您就可以向Parameters集合添加任何类型的对象。

If you want to use it to actually display the properties of a specific object, it only takes a few lines to load up the Parameters collection with the appropriate objects. 如果要使用它来实际显示特定对象的属性,只需几行就可以使用适当的对象加载Parameters集合。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM