如何绘制嵌入在ListView中的Canvas小部件
本文关键字:ListView 中的 Canvas 小部 何绘制 绘制 | 更新日期: 2023-09-27 18:17:00
这是一个非常基本的要求,但我卡住了!WPF/。我只是想动态地绘制到我的ListView的画布列。一次失败尝试:
<ListView name="myGridView">
<GridViewColumn Header="ColumnA" DisplayMemberBinding="{Binding Path=ColumnA}" />
<GridViewColumn DisplayMemberBinding="{Binding Path=ColumnB}">
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SUSPECT!
<Canvas Name="canvasColumn" Width="100" Height="20" />
</GridViewColumn>
</GridView>
在我的代码中,我有一个类"MyData"与字段绑定到非画布ListView列。我循环一些"Whatever"在ListView中创建项目:
foreach (Whatever whatever in whatevers)
{
MyData myData = new MyData();
myData.ColumnA = whatever.A;
myData.ColumnB = new Canvas();
Line line = new Line();
line.Stroke = System.Windows.Media.Brushes.Black;
line.X1 = line.Y1 = 1;
line.X2 = line.Y2 = 100;
line.StrokeThickness = 1;
myData.ColumnB.Children.Add(line);
myListView.Items.Add(myData);
}
这行不通:屏幕上画布列的每一行都显示文本"System.Windows.Controls.Canvas"。这并不奇怪—我以与文本列相同的方式绑定了列,并且似乎开始了类型名的toString转换。但是,我已经尝试了一些其他的事情,只是不能得到画布显示。
我还尝试删除上面标记为"嫌疑犯"的列绑定,以及myData的ColumnB字段,寻求一种通过列表视图引用画布小部件的方法,即某种形式:
myListView.reference-to-new-row-and-canvas-column = theNewCanvasIDrewOn;
我的一些搜索已经出现了样式,ItemPanel配置等丑陋的混乱:请-如果这是必要的,我至少希望它可以保持最小....
请多多指教。
欢呼,托尼
<标题> 更新对于我来说,最小的解决方案似乎是在App.xaml的应用程序中添加一个DataTemplate。资源标记:<DataTemplate x:Key="myTemplate">
<Canvas Width="60" Height="20" Background="Red" ClipToBounds="True" >
<ContentPresenter Content="{Binding myCanvasField}" />
</Canvas>
</DataTemplate>
并将GridViewColumn定义为:
<GridViewColumn CellTemplate="{StaticResource myTemplate}" Header="title" />
感谢Dean为我指出了正确的方向,并为画布特定的细节绑定到画布。然后,我"绘制"我添加到ListView的对象的Canvas属性成员。
标题>你需要使用CellTemplate而不是直接使用Canvas
http://msdn.microsoft.com/en-us/library/system.windows.controls.gridviewcolumn.celltemplate.aspx你可以实现TaskVisualizer作为一个自定义控件,然后在你的列表模板中托管它。这样可以将任务可视化代码与全局UI代码分开。这样做的好处是可以很容易地在其他地方重用任务可视化-例如,当您将鼠标悬停在其他视图中的任务上时,可以很容易地在工具提示中显示相同的图形。
以下是我的看法。其思想是使用迷你DSL在画布和业务对象之间交换信息。
XAML:<Window x:Class="DrawInCanvas.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DrawInCanvas"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid x:Name="g">
<DataGrid.Columns>
<DataGridTextColumn Header="Id" Binding="{Binding Item1}" />
<DataGridTemplateColumn Header="Bar">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Canvas HorizontalAlignment="Left"
Height="20"
local:CanvasDrawing.Drawing="{Binding Item2}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
代码:using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace DrawInCanvas
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
// just a sample
Dictionary<int, string> barDefinitions = new Dictionary<int, string>(3)
{
{ 1, "100$red" },
{ 2, "220$yellow" },
{ 3, "40$blue" }
};
this.g.ItemsSource =
Enumerable.Range(1, 3).Select(t =>
new Tuple<int, string>(t, barDefinitions[t]));
}
}
public class CanvasDrawing : DependencyObject
{
public static readonly DependencyProperty DrawingProperty =
DependencyProperty.RegisterAttached("Drawing",
typeof(string),
typeof(CanvasDrawing),
new PropertyMetadata(new PropertyChangedCallback((o, e) =>
{
CanvasDrawing.Draw((Canvas)o, (string)e.NewValue);
})));
public static void SetDrawing(Canvas canvas, string drawing)
{
canvas.SetValue(CanvasDrawing.DrawingProperty, drawing);
}
public static string GetDrawing(Canvas canvas)
{
return (string)canvas.GetValue(CanvasDrawing.DrawingProperty);
}
private static void Draw(Canvas canvas, string drawing)
{
string[] parts = drawing.Split("$".ToCharArray());
canvas.Width = double.Parse(parts[0]);
canvas.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString(parts[1]));
}
}
}