Tim*_*oth 3 c# data-binding wpf xaml
我有一个绑定到可观察集合的 ItemsControl。在控件 ItemTemplate 中,我有一个 Canvas,其中包含我绘制一些线段的路径。像这样:
<ItemsControl
ItemsSource="{Binding CombinedPieChartData}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Canvas>
<Path Stroke="Black" StrokeThickness="1" Fill="{Binding Color}">
<Path.Data>
<GeometryGroup>
<PathGeometry>
<PathFigure StartPoint="{Binding FirstPoint1}">
<PathFigure.Segments>
<LineSegment Point="{Binding SecondPoint1}"/>
</PathFigure.Segments>
</PathFigure>
</PathGeometry>
</GeometryGroup>
</Path.Data>
</Path>
</Canvas>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)
将 Path 的 Fill 属性绑定到 Color 属性工作正常。但是绑定到 PathFigure 的 StartPoint 和 LineSegments Point 不起作用。它显示正确,但它报告这些错误:
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=FirstPoint1; DataItem='PieChartDataPoint' (HashCode=35164785); target element is 'PathFigure' (HashCode=9043297); target property is 'StartPoint' (type 'Point')
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=SecondPoint1; DataItem='PieChartDataPoint' (HashCode=35164785); target element is 'LineSegment' (HashCode=52141992); target property is 'Point' (type 'Point')
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=FirstPoint1; DataItem='PieChartDataPoint' (HashCode=52449849); target element is 'PathFigure' (HashCode=8195173); target property is 'StartPoint' (type 'Point')
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=SecondPoint1; DataItem='PieChartDataPoint' (HashCode=52449849); target element is 'LineSegment' (HashCode=41799477); target property is 'Point' (type 'Point')
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=FirstPoint1; DataItem='PieChartDataPoint' (HashCode=15121425); target element is 'PathFigure' (HashCode=46419306); target property is 'StartPoint' (type 'Point')
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=SecondPoint1; DataItem='PieChartDataPoint' (HashCode=15121425); target element is 'LineSegment' (HashCode=50982559); target property is 'Point' (type 'Point')
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=FirstPoint1; DataItem=null; target element is 'PathFigure' (HashCode=61646970); target property is 'StartPoint' (type 'Point')
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=SecondPoint1; DataItem=null; target element is 'LineSegment' (HashCode=38860075); target property is 'Point' (type 'Point')
Run Code Online (Sandbox Code Playgroud)
我真的很困惑为什么会出现这些错误并且无法在线找到任何帮助。有什么建议?
这是我在 Observable 集合中使用的类
public class PieChartDataPoint : ObservableObject
{
public string Catagory { get; set; }
public double Value { get; set; }
public SolidColorBrush Color { get; set; }
private Point firstPoint1;
public Point FirstPoint1
{
get
{
return firstPoint1;
}
set
{
firstPoint1 = value;
RaisePropertyChangedEvent("FirstPoint1");
}
}
private Point secondPoint1;
public Point SecondPoint1
{
get
{
return secondPoint1;
}
set
{
secondPoint1 = value;
RaisePropertyChangedEvent("SecondPoint1");
}
}
private Size pieSize;
public Size PieSize
{
get
{
return pieSize;
}
set
{
pieSize = value;
RaisePropertyChangedEvent("PieSize");
}
}
private int colorIndex = 0;
public int ColorIndex
{
get { return colorIndex; }
set
{
colorIndex = value;
Color newColor = Utilities.SelectColour(value);
newColor.A = 190;
this.Color = new SolidColorBrush(newColor);
}
}
public double Fraction { get; set; }
public string Percentage
{
get
{
return String.Format("{0:P2}", Fraction);
}
}
public PieChartDataPoint(string Catagory, double Value, int ColorIndex, double Fraction)
{
this.Catagory = Catagory;
this.Value = Value;
this.ColorIndex = ColorIndex;
this.Fraction = Fraction;
}
}
Run Code Online (Sandbox Code Playgroud)
因此,在您的 xaml 中,您设置了 Path 的 Data 属性。此属性属于 Geometry 类型,它不是可视化树的一部分(几何体本身不是可视化控件 - 它用于渲染路径)。这意味着:它不继承“父”DataContext,因为它实际上不在可视化树中并且没有父级(比这更复杂一点,因为一些非可视化元素确实继承了DataContext,但不在此案件)。
您可以做的是在您的 DataTemplate 中创建“假”元素,该元素将继承父 DataContext,然后将其用作绑定的源。没有任何“假”元素会做,请参阅这篇文章:http : //www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not -遗传/
现在,从那篇文章中复制 BindingProxy 类,然后:
<ItemsControl
ItemsSource="{Binding CombinedPieChartData}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Canvas>
<Canvas.Resources>
<local:BindingProxy x:Key="proxy" Data="{Binding}" />
</Canvas.Resources>
<Path Stroke="Black" StrokeThickness="1" Fill="{Binding Color}">
<Path.Data>
<GeometryGroup>
<PathGeometry>
<PathFigure StartPoint="{Binding Source={StaticResource proxy}, Path=Data.FirstPoint1}">
<PathFigure.Segments>
<LineSegment Point="{Binding Source={StaticResource proxy}, Path=Data.SecondPoint1}"/>
</PathFigure.Segments>
</PathFigure>
</PathGeometry>
</GeometryGroup>
</Path.Data>
</Path>
</Canvas>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)
您所做的是在您的可视元素的资源中创建“代理”控件,该控件以特殊方式构造(从 Freezable 继承 - 请参阅上面的文章),并且尽管不是可视化树的一部分,但将继承父 DataContext。然后您只需将该代理用作绑定的来源。