C# ItemsControl中的矩形间距和对齐
我上过这门课:C# ItemsControl中的矩形间距和对齐,c#,wpf,itemscontrol,C#,Wpf,Itemscontrol,我上过这门课: public class MyRect : FrameworkElement { public Visual Visual { get; set; } protected override int VisualChildrenCount => 1; protected override Visual GetVisualChild(int index) => Visual; protected override void OnRender
public class MyRect : FrameworkElement
{
public Visual Visual { get; set; }
protected override int VisualChildrenCount => 1;
protected override Visual GetVisualChild(int index) => Visual;
protected override void OnRender(DrawingContext drawingContext)
{
var drawing = new DrawingVisual();
using (var dc = drawing.RenderOpen())
{
var brush = new SolidColorBrush(Colors.Green);
var pen = new Pen(new SolidColorBrush(Colors.Blue), 1);
var rect = new Rect(new Size(Width, Height));
dc.DrawRectangle(brush, pen, rect);
}
Visual = drawing;
}
}
用于绘制矩形。单击按钮后,一个新的矩形
将添加到名为RectCollection
的可观察集合
:
RectCollection.Insert(0, new MyRect() {Width = 20, Height = rand.NextDouble() * 100 });
而RectCollection
是ItemsControl
的ItemSource
:
<ItemsControl ItemsSource="{Binding RectCollection}" VerticalAlignment="Bottom" VerticalContentAlignment="Bottom">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
那不行!另一个问题是VerticalContentAlignment=“Bottom”
没有将底部的矩形与基线对齐
编辑
public class MyRect : FrameworkElement
{
public Visual Visual { get; set; }
protected override int VisualChildrenCount => 1;
protected override Visual GetVisualChild(int index) => Visual;
protected override void OnRender(DrawingContext drawingContext)
{
var drawing = new DrawingVisual();
using (drawingContext = drawing.RenderOpen())
{
var grid = new Grid();
grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(0, GridUnitType.Star) });
grid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
var text = new TextBlock()
{
Text = Height.ToString("N2"),
Foreground = new SolidColorBrush(Colors.Black),
LayoutTransform = new RotateTransform(-90),
VerticalAlignment = VerticalAlignment.Top,
Margin = new Thickness(0, 0, 0, 5)
};
var border = new Border()
{
Width = Width,
Height = Height,
Background = new SolidColorBrush(Colors.Green),
CornerRadius = new CornerRadius(5, 5, 0, 0)
};
grid.Children.Add(text);
grid.Children.Add(border);
Grid.SetRow(border, 1);
grid.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
drawingContext.DrawRectangle(new VisualBrush(grid), null, new Rect(grid.DesiredSize));
}
Visual = drawing;
}
}
下面是一个简单条形图的示例,仅使用ItemsControl的ItemTemplate中的一些基本元素:
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Width="20" Height="100" Margin="2">
<Rectangle VerticalAlignment="Bottom"
Height="{Binding}"
Fill="LightGray"/>
<TextBlock Text="{Binding StringFormat={}{0:N2}}">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"/>
</TextBlock.LayoutTransform>
</TextBlock>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
这看起来很奇怪。在ItemTemplate中使用矩形元素和MyRect项目类,如下所示:。不要在视图模型中使用UI元素(如MyRect)。@Clemens,它实际上有一个
TextBlock
和一个Border
,如编辑部分所示。它仍然应该是一个UserControl,在ItemTemplate中实例化。你现在所拥有的是非常低效的。视图模型中不应该有UI元素。@Clemens,请给出一个带有UserControl
的简单示例。它实际上是一个简单的条形图,上面有值。UserControl是一个控件,它有自己的XAML,您可以在其中定义它的视觉外观。互联网上有很多例子。
<ItemsControl ItemsSource="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Width="20" Height="100" Margin="2">
<Rectangle VerticalAlignment="Bottom"
Height="{Binding}"
Fill="LightGray"/>
<TextBlock Text="{Binding StringFormat={}{0:N2}}">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"/>
</TextBlock.LayoutTransform>
</TextBlock>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Random r = new Random();
DataContext = Enumerable.Range(0, 20).Select(i => r.NextDouble() * 100);