我编写了一个在画布中绘制元素的应用程序。这些元素是矩形(但我使用了 Border 类,因为我想在其中插入文本)。这些元素代表对象(在我的例子中是任务)。
我在代码后面绘制这些元素,如下所示:
foreach (var task in TasksList)
{
var rect = new Border();
rect.Background = (SolidColorBrush)(new
BrushConverter().ConvertFrom("#0074D9"));
rect.BorderBrush = (SolidColorBrush)(new
BrushConverter().ConvertFrom("#001f3f"));
rect.BorderThickness = new Thickness(2);
rect.Width = 60;
rect.Height = 60;
var t = new TextBlock
{
Text = task.Id.ToString(),
Foreground = new SolidColorBrush(Colors.White),
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
};
rect.Child = t;
Canvas.SetLeft(rect, coordX);
Canvas.SetTop(rect, coordY);
Canvas.Children.Add(rect);
}
在代码后面设计边框(矩形)。我想将其设计为 XAML 资源,并在代码隐藏中创建此资源的实例。如何做到这一点? 在这种情况下如何使用绑定?例如,在 xaml 资源中,我需要定义任务的属性 ID 需要绑定到放置在边框中间的文本块的 Text 属性。但稍后,在代码隐藏中,如何指定 xaml 中定义的属性的数据上下文?
希望你能指导我。谢谢
目前还不清楚坐标值来自哪里,所以我将它们变成了TaskItem
类的一部分。您可以根据需要更改此方面。
为了在 WPF XAML 中实现代码,您需要项的可视表示形式 (DataTemplate
) 和确定项放置的方法 - 我为此使用样式。这些物品将按照克莱门斯的建议,用ItemsControl
放置在画布上。
对于此示例,任务项是一个普通类。如果要在创建后修改其内容,最好使用INotifyPropertyChanged
.
public class TaskItem
{
public int Id { get; set; }
public double CoordX { get; set; }
public double CoordY { get; set; }
}
xaml,期望DataContext
包含TasksList
集合:
<Window.Resources>
<DataTemplate x:Key="dtTaskItem" DataType="{x:Type local:TaskItem}">
<Border
Background="#0074D9"
BorderBrush="#001F3F"
BorderThickness="2"
Width="60"
Height="60">
<TextBlock
Text="{Binding Id}"
Foreground="White"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</DataTemplate>
<Style x:Key="canvasTaskItemStyle" TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding CoordX}"/>
<Setter Property="Canvas.Top" Value="{Binding CoordY}"/>
</Style>
</Window.Resources>
<Grid x:Name="grid1">
<ItemsControl
ItemsSource="{Binding TasksList}"
ItemTemplate="{StaticResource dtTaskItem}"
ItemContainerStyle="{StaticResource canvasTaskItemStyle}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
还有一些示例数据可供使用:
var tasksList = new List<TaskItem>()
{
new TaskItem { Id = 1, CoordX = 10, CoordY = 20 },
new TaskItem { Id = 2, CoordX = 60, CoordY = 160 },
new TaskItem { Id = 5, CoordX = 140, CoordY = 80 },
new TaskItem { Id = 3, CoordX = 50, CoordY = 50 },
new TaskItem { Id = 8, CoordX = 100, CoordY = 100 },
};
grid1.DataContext = new { TasksList = tasksList };
旁注:资源也可以放在Grid.Resources
部分中。该Window.Resources
只是我在测试某些与 WPF 相关的堆栈溢出问题的答案时使用的默认构建。local:TaskItem
期望为当前项目定义 xaml 命名空间(在我的例子中是xmlns:local="clr-namespace:WpfTests_2"
)。