WPF:将资源元素添加到画布和绑定属性



我编写了一个在画布中绘制元素的应用程序。这些元素是矩形(但我使用了 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")。

最新更新