C# 带有ItemsControl的网格中的Gridsplitter
我正在尝试创建一个PropertyGrid自定义控件。PropertyGrid与VisualStudio中使用的PropertyGrid非常相似。我已经尝试使用扩展WPF工具包中的PropertyGrid,但是您必须使用属性指定属性的类别,并且我们需要在运行时更改类别。据我所知,这是不可能的属性 所以我自己做房地产网格。这是我目前的代码: Generic.xaml文件:C# 带有ItemsControl的网格中的Gridsplitter,c#,wpf,custom-controls,wpftoolkit,itemscontrol,C#,Wpf,Custom Controls,Wpftoolkit,Itemscontrol,我正在尝试创建一个PropertyGrid自定义控件。PropertyGrid与VisualStudio中使用的PropertyGrid非常相似。我已经尝试使用扩展WPF工具包中的PropertyGrid,但是您必须使用属性指定属性的类别,并且我们需要在运行时更改类别。据我所知,这是不可能的属性 所以我自己做房地产网格。这是我目前的代码: Generic.xaml文件: <ResourceDictionary xmlns="http://schemas.microsoft.com/winf
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:HomeMadePropertyGrid"
xmlns:System="clr-namespace:System;assembly=mscorlib">
<BooleanToVisibilityConverter x:Key="BoolToVisConverter"></BooleanToVisibilityConverter>
<SolidColorBrush x:Key="GlyphBrush" Color="#444" />
<ControlTemplate x:Key="toggleButtonTemplate" TargetType="ToggleButton">
<Grid Width="15" Height="13" Background="Transparent">
<Path x:Name="ExpandPath" Fill="{StaticResource GlyphBrush}" Data="M 4 0 L 8 4 L 4 8 Z" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="1,1,1,1" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Data" TargetName="ExpandPath" Value="M 0 4 L 8 4 L 4 8 Z"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="toggleButtonStyle" TargetType="ToggleButton">
<Setter Property="Template" Value="{StaticResource toggleButtonTemplate}" />
</Style>
<Style TargetType="{x:Type local:PropertyGrid}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:PropertyGrid}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ItemsControl ItemsSource="{TemplateBinding ItemsSource}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Background="{Binding GridColor, RelativeSource={RelativeSource AncestorType=local:PropertyGrid}}">
<StackPanel Orientation="Horizontal">
<ToggleButton x:Name="toggleButton" Height="20" Width="20" Style="{StaticResource toggleButtonStyle}"/>
<TextBlock Text="{Binding Name}" FontWeight="Bold"></TextBlock>
</StackPanel>
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Visibility="{Binding ElementName=toggleButton, Path=IsChecked, Converter={StaticResource BoolToVisConverter}}"
Grid.IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border BorderThickness="1" BorderBrush="{Binding GridColor, RelativeSource={RelativeSource AncestorType=local:PropertyGrid}}">
<TextBlock Background="White" Text="{Binding Path=Name}"/>
</Border>
<GridSplitter Width="1"
Grid.RowSpan="4" Grid.Column="1"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Background="{Binding GridColor, RelativeSource={RelativeSource AncestorType=local:PropertyGrid}}"/>
<Border Grid.Column="2" BorderThickness="1" BorderBrush="{Binding GridColor, RelativeSource={RelativeSource AncestorType=local:PropertyGrid}}">
<ContentPresenter Grid.Column="2" Content="{Binding Value}">
<ContentPresenter.Resources>
<DataTemplate DataType="{x:Type System:String}">
<TextBox Text="{Binding Path=Content, RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}"
BorderThickness="0"/>
</DataTemplate>
<DataTemplate DataType="{x:Type System:Int32}">
<TextBox Text="{Binding Path=Content, RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}"
TextAlignment="Right"
BorderThickness="0"/>
</DataTemplate>
<DataTemplate DataType="{x:Type System:Double}">
<TextBox Text="{Binding Path=Content, RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}"
TextAlignment="Right"
BorderThickness="0"/>
</DataTemplate>
<DataTemplate DataType="{x:Type System:Boolean}">
<CheckBox IsChecked="{Binding Path=Content, RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}"
HorizontalAlignment="Center"/>
</DataTemplate>
</ContentPresenter.Resources>
</ContentPresenter>
</Border>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
PropertyGroup
public class PropertyGroup
{
public string Name { get; set; }
public List<PropertyGridItem> Items { get; set; }
public PropertyGroup()
{
Items = new List<PropertyGridItem>();
Name = "";
}
}
my MainWindow.xaml中的以下代码:
<local:PropertyGrid ItemsSource="{Binding Path=Groups}" GridColor="#f0f0f0"/>
视图模型
public class ViewModel
{
public List<PropertyGroup> Groups { get; set; }
public ViewModel()
{
Groups = new List<PropertyGroup>();
PropertyGroup group1 = new PropertyGroup();
group1.Name = "Group1";
group1.Items.Add(new PropertyGridItem("Item1", "test"));
group1.Items.Add(new PropertyGridItem("Item2", 300));
group1.Items.Add(new PropertyGridItem("Item3", true));
group1.Items.Add(new PropertyGridItem("Item4", 5.2));
Groups.Add(group1);
PropertyGroup group2 = new PropertyGroup();
group2.Name = "Group2";
group2.Items.Add(new PropertyGridItem("Item1", "test"));
group2.Items.Add(new PropertyGridItem("Item2", 300));
group2.Items.Add(new PropertyGridItem("Item3", true));
group2.Items.Add(new PropertyGridItem("Item4", 5.2));
Groups.Add(group2);
}
}
公共类视图模型
{
公共列表组{get;set;}
公共视图模型()
{
组=新列表();
PropertyGroup group1=新的PropertyGroup();
group1.Name=“group1”;
第1组。项目。添加(新的PropertyGridItem(“项目1”,“测试”);
组1.项目。添加(新的PropertyGridItem(“项目2”,300));
group1.Items.Add(新的PropertyGridItem(“Item3”,true));
第1组。项目。添加(新的PropertyGridItem(“项目4”,5.2));
添加(第1组);
PropertyGroup group2=新的PropertyGroup();
group2.Name=“group2”;
第2组。项目。添加(新的PropertyGridItem(“项目1”,“测试”);
组2.项目。添加(新的PropertyGridItem(“项目2”,300));
组2.Items.Add(新的PropertyGridItem(“Item3”,true));
第2组。项目。添加(新的PropertyGridItem(“项目4”,5.2));
添加(第2组);
}
}
我遇到的问题是GridSplitter应用于每一行。我希望GridSplitter应用于组中的所有行。我明白这是因为我为每一项都创建了一个新的网格。要使附着的特性正常工作,项必须是网格的直接子项。
DataGrid也不是选项,因为GridSplitter仅在列标题之间可用
因此,长话短说:我如何在ItemsControl中使用网格以及网格拆分器,如果不可能的话,它可以应用于理想情况下一个组的所有行或整个网格。不幸的是,您没有为我们提供一段只演示您的问题的简单代码,我没有时间让它在我的应用程序中编译和运行测试项目,所以我只能给你建议,而不是测试的解决方案。下次,请花点时间展示一个代码示例,我们可以将其复制并粘贴到项目中 如果您使用以下命令加入所有行
网格
,则可能能够获得“拉伸的”GridSplitter
:
...
我终于找到了这个问题的解决方案
为了让它发挥作用,我必须:
- 在父项控件上将Grid.IsSharedSizeScope设置为true
- 使用任意名称在名称列上设置SharedSizeGroup属性
- 删除“名称”列上的星形大小。由于某种原因,第一列和第三列都带有星形大小,导致GridSplitter卡住
- 在GridSplitter上设置固定宽度,我将宽度设置为2
- 将GridSplitter的ResizeBehaviour设置为Previous和Next李>
<ItemsControl ItemsSource="{Binding Items}" Grid.IsSharedSizeScope="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Visibility="{Binding ElementName=toggleButton, Path=IsChecked, Converter={StaticResource BoolToVisConverter}}" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="nameColumn"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Style="{StaticResource BodyPropertyGrid_CellBorder}">
<TextBlock Text="{Binding Path=Name}"/>
</Border>
<GridSplitter Grid.Column="1" Width="2"
ResizeBehavior="PreviousAndNext"
Style="{StaticResource BodyPropertyGridSplitter}"/>
<Border Grid.Column="2" Style="{StaticResource BodyPropertyGrid_CellBorder}">
<ContentControl Content="{Binding}"
ContentTemplateSelector="{StaticResource propertyItemTemplateSelector}"/>
</Border>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
感谢您的快速回答。不幸的是,它没有起作用。GridSplitter无法再移动,列具有自动宽度。很抱歉,之前没有添加测试代码。我编辑了我的问题并添加了制作测试项目所需的所有代码。这就是我所需要的!你能分享你的代码源吗?@twister0k我在问答中分享的内容几乎是我能分享的全部。通过这段代码,您应该能够创建一个简单的属性网格。有什么特别的问题我可以帮你解决吗?谢谢你的回答。我根据你的代码做了一个简单的项目,但是,我不知道为什么,它不起作用。如果你有时间,请看我更正了你的代码并上传了它。该代码包含一个有效的解决方案。它不起作用的原因是因为您没有对属性网格进行自定义控件。它起作用了。谢谢但是现在,我遇到了与您之前遇到的相同的问题,GridSplitter应用于每一行。
public MainWindow()
{
InitializeComponent();
this.DataContext = new ViewModel();
}
public class ViewModel
{
public List<PropertyGroup> Groups { get; set; }
public ViewModel()
{
Groups = new List<PropertyGroup>();
PropertyGroup group1 = new PropertyGroup();
group1.Name = "Group1";
group1.Items.Add(new PropertyGridItem("Item1", "test"));
group1.Items.Add(new PropertyGridItem("Item2", 300));
group1.Items.Add(new PropertyGridItem("Item3", true));
group1.Items.Add(new PropertyGridItem("Item4", 5.2));
Groups.Add(group1);
PropertyGroup group2 = new PropertyGroup();
group2.Name = "Group2";
group2.Items.Add(new PropertyGridItem("Item1", "test"));
group2.Items.Add(new PropertyGridItem("Item2", 300));
group2.Items.Add(new PropertyGridItem("Item3", true));
group2.Items.Add(new PropertyGridItem("Item4", 5.2));
Groups.Add(group2);
}
}
<Grid Visibility="{Binding ElementName=toggleButton, Path=IsChecked, Converter=
{StaticResource BoolToVisConverter}}" Grid.IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" SharedSizeGroup="FirstColumn" />
<ColumnDefinition Width="Auto" SharedSizeGroup="GridSplitterColumn" />
<ColumnDefinition Width="*" SharedSizeGroup="LastColumn" />
</Grid.ColumnDefinitions>
...
</Grid>
<ItemsControl ItemsSource="{Binding Items}" Grid.IsSharedSizeScope="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Visibility="{Binding ElementName=toggleButton, Path=IsChecked, Converter={StaticResource BoolToVisConverter}}" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="nameColumn"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Style="{StaticResource BodyPropertyGrid_CellBorder}">
<TextBlock Text="{Binding Path=Name}"/>
</Border>
<GridSplitter Grid.Column="1" Width="2"
ResizeBehavior="PreviousAndNext"
Style="{StaticResource BodyPropertyGridSplitter}"/>
<Border Grid.Column="2" Style="{StaticResource BodyPropertyGrid_CellBorder}">
<ContentControl Content="{Binding}"
ContentTemplateSelector="{StaticResource propertyItemTemplateSelector}"/>
</Border>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>