WPF:将资源元素添加到画布和绑定属性 [英] WPF: Adding resource element to canvas and binding properties
问题描述
我编写了一个在画布上绘制元素的应用程序。这些元素是矩形(但我使用Border类是因为我想在其中插入文本)。这些元素代表对象(在我的案例中为Tasks)。
I have programmed an application that draws elements in a canvas. These elements are Rectangles (but I used the Border class because I want to instert text in it). These elements represent objects (Tasks in my case).
我在代码后面绘制这些元素,如下所示:
I draw these elements in code behind like this:
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需要绑定到位于边框中间的TextBlock的Text属性。但是后来,在后面的代码中,如何指定xaml中定义的属性的DataContext?
Insted of designing the border (rect) in code behind. I would like to design it as a XAML resource and create instances of this resources in code behind. How can accomplish this? How can I use bindings in this case? For instance, in the xaml resource I need to define that the property ID of the task needs to be binded to the Text property of a TextBlock placed in the middle of the border. But later, in the code behind, how do I specify the DataContext of the properties defined in the xaml?
希望您可以指导我。谢谢
Hope you could guide me. Thanks
推荐答案
目前尚不清楚坐标值从何而来,所以我将其转换为 TaskItem
类。您可以根据需要更改此方面。
It's not really clear where the coordinate values come from, so I turned them into part of the TaskItem
class. You can change this aspect however you may want.
为了在WPF XAML中实现代码,您需要直观地表示该项目( DataTemplate
)和确定项目位置的方法-我在这方面使用了一种样式。这些项目将使用Clemens建议的 ItemsControl
放在画布上。
In order to realize your code in WPF XAML, you need a visual representation of the item (DataTemplate
) and a way to determine the item placement - I use a style for this aspect. The items will be placed on the canvas with an ItemsControl
as suggested by Clemens.
TaskItem是一个普通类对于这个例子。如果要在创建后修改其内容,则最好使用 INotifyPropertyChanged
来实现。
The TaskItem is a plain class for this example. If you want to modify its contents after creation, you should better implement it with INotifyPropertyChanged
.
public class TaskItem
{
public int Id { get; set; }
public double CoordX { get; set; }
public double CoordY { get; set; }
}
xaml,期望使用 DataContext
包含 TasksList
集合:
The xaml, expecting the DataContext
to contain a TasksList
collection:
<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>
还有一些示例数据可用于:
And some example data to play with:
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相关的stackoverflow问题的答案时使用的默认版本。 local:TaskItem
期望为当前项目定义xaml命名空间(在我的情况下 xmlns:local = clr-namespace:WpfTests_2
)。
Sidenote: the resources could as well be placed inside a Grid.Resources
section. The Window.Resources
is just a default build I use when testing my answers to some WPF related stackoverflow question. The local:TaskItem
expects the xaml namespace to be defined for the current project (In my case xmlns:local="clr-namespace:WpfTests_2"
).
这篇关于WPF:将资源元素添加到画布和绑定属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!