WPF属性面板类似于Visual Studio的

时间:2010-05-12 16:11:00

标签: c# wpf .net-4.0

只是想知道他们的任何示例或元素看起来与Visual Studio中使用的“属性”面板非常相似?我猜Visual Studio 2010中的那个基于WPF,几乎肯定是树视图?

2 个答案:

答案 0 :(得分:4)

答案 1 :(得分:3)

如果您想使用一些简单的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>

这是

背后的代码
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));
  }
}

此属性网格在WPF中更好用的原因是,只要具有Category,DisplayName和Description,就可以向Parameters集合添加任何类型的对象。

如果要使用它来实际显示特定对象的属性,只需几行就可以使用适当的对象加载Parameters集合。