我的问题是:在我的程序中,我让用户在画布上放置形状(类DrawingShape)。绘图形状封装了堆叠的路径和标签:
<UserControl x:Class="HandballTrainerFluent.Graphics.DrawingShape"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="60"
d:DesignWidth="60"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid x:Name="container" Width="Auto" Height="Auto">
<Grid.RowDefinitions>
<RowDefinition Height="38"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Canvas x:Name="geometryCanvas" HorizontalAlignment="Center" Grid.Row="0" Width="38" Height="38">
<Path x:Name="Path"
Width="35.8774"
Height="31.2047"
Canvas.Left="1.0613"
Canvas.Top="3.29528"
Stretch="Fill"
StrokeLineJoin="Round"
Stroke="{Binding OutlineBrush,Mode=OneWay}"
StrokeThickness="{Binding OutlineWidth,Mode=OneWay}"
StrokeDashArray="{Binding OutlinePattern,Mode=OneWay}"
Fill="{Binding FillBrush,Mode=OneWay}"
Data="F1 M 19,3.79528L 1.5613,34L 36.4387,34L 19,3.79528 Z "/>
</Canvas>
<TextBlock x:Name="TextBox" HorizontalAlignment="Center" Grid.Row="1" Text="{Binding LabelText,Mode=OneWay}"></TextBlock>
</Grid>
</UserControl>因此,一些可视设置和标签文本绑定到代码隐藏文件的属性。
在用这些绘图形状反序列化画布之后,我需要恢复XAML和代码隐藏文件之间的绑定。我试过了,但似乎行不通:
private void RepairBindingsAfterLoading()
{
foreach (UIElement element in this.drawingCanvas.Children)
{
if (element.GetType() == typeof(DrawingShape))
{
DrawingShape shape = (DrawingShape)element;
BindingOperations.ClearAllBindings(shape.Path);
BindingOperations.ClearAllBindings(shape.TextBox);
BindingOperations.ClearAllBindings(shape);
shape.BeginInit();
Binding dataContextBinding = new Binding();
dataContextBinding.RelativeSource = RelativeSource.Self;
shape.SetBinding(DrawingShape.DataContextProperty, dataContextBinding);
Binding fillBinding = new Binding("FillBrush");
shape.Path.SetBinding(Path.FillProperty, fillBinding);
Binding outlineBinding = new Binding("OutlineBrush");
shape.Path.SetBinding(Path.StrokeProperty, outlineBinding);
Binding widthBinding = new Binding("OutlineWidth");
shape.Path.SetBinding(Path.StrokeThicknessProperty, widthBinding);
Binding patternBinding = new Binding("OutlinePattern");
shape.Path.SetBinding(Path.StrokeDashArrayProperty, patternBinding);
Binding labelTextBinding = new Binding("LabelText");
shape.TextBox.SetBinding(TextBlock.TextProperty, labelTextBinding);
shape.EndInit();
shape.UpdateLayout();
}
}
}无论我对代码隐藏属性(例如,更改FillBrush)做了什么,显示的DrawingShape的可视化都不会更新。我是不是错过了重要的一步?
在看到这个问题后,我添加了shape.BeginUpdate()和shape.EndUpdate():Bindings not applied to dynamically-loaded xaml
非常感谢你的见解
编辑2012-09-25
查看另一段不依赖于任何绑定的代码,我想知道,我是否能够通过x:Name反序列化引用Xaml-定义中的任何元素。以下回调不会对形状执行任何操作:
private void rotateClockwiseMenuItem_Click(object sender, RoutedEventArgs e)
{
if(this.drawingCanvas.SelectedItem.GetType() == typeof(DrawingShape))
{
DrawingShape shape = (DrawingShape)this.drawingCanvas.SelectedItem;
TransformGroup transformStack = new TransformGroup();
transformStack.Children.Add(shape.geometryCanvas.LayoutTransform);
transformStack.Children.Add(new RotateTransform(90));
shape.geometryCanvas.LayoutTransform = transformStack;
}
}调试告诉我,shape的内容似乎恰到好处。当我执行一次命令时,shape.geometryCanvas.LayoutTransform是标识矩阵。当第二次执行时,shape.geometryCanvas.LayoutTransform是两个元素的TransformGroup。
它看起来像是geometryCanvas的引用(在Xaml中声明)并不是屏幕上使用的引用。
发布于 2012-09-25 08:20:50
明白了!
我不知道您不能成功地在反序列化之后从代码隐藏文件外部引用x:Name'd XAML元素(这似乎是当前的问题)。
解决方案之一是在FindName()上使用UserControl,例如:
TextBlock textBox = shape.FindName("TextBox") as TextBlock;完整和正确的RepairBindingsAfterLoading()如下所示:
private void RepairBindingsAfterLoading()
{
foreach (UIElement element in this.drawingCanvas.Children)
{
if (element.GetType() == typeof(DrawingShape))
{
DrawingShape shape = (DrawingShape)element;
shape.DataContext = shape;
Path path = shape.FindName("Path") as Path;
Binding fillBinding = new Binding("FillBrush");
path.SetBinding(Path.FillProperty, fillBinding);
Binding outlineBinding = new Binding("OutlineBrush");
path.SetBinding(Path.StrokeProperty, outlineBinding);
Binding widthBinding = new Binding("OutlineWidth");
path.SetBinding(Path.StrokeThicknessProperty, widthBinding);
Binding patternBinding = new Binding("OutlinePattern");
path.SetBinding(Path.StrokeDashArrayProperty, patternBinding);
TextBlock textBox = shape.FindName("TextBox") as TextBlock;
Binding labelTextBinding = new Binding("LabelText");
textBox.SetBinding(TextBlock.TextProperty, labelTextBinding);
}
}
}只是为了记录下,我的笨拙
BindingOperations.ClearAllBindings(shape.Path);
BindingOperations.ClearAllBindings(shape.TextBox);
BindingOperations.ClearAllBindings(shape);它的工作原理就像dbaseman建议的更简单、更优雅的解决方案:
shape.DataContext = this;希望这能帮助别人避免我的错误:-)
https://stackoverflow.com/questions/12572936
复制相似问题