私の問題は次のとおりです。私のプログラムでは、ユーザーがキャンバスにシェイプ (クラス DrawingShape) を配置できるようにしています。Drawing Shape は、積み重ねられたパスとラベルをカプセル化します。
<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>
したがって、一部のビジュアル設定とラベル テキストは分離コード ファイルのプロパティにバインドされます。
これらの Drawing 図形を使用して Canvas を逆シリアル化した後、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 dynamic-loaded xaml
洞察に感謝します
編集 2012-09-25
バインドに依存しない別のコードを見ると、逆シリアル化後に x:Name を介して Xaml-Definition の要素を実際に参照できるかどうか疑問に思います。次のコールバックは、シェイプに対して何も行いません。
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
見えることがわかります。コマンドを 1 回実行するshape.geometryCanvas.LayoutTransform
と、恒等行列になります。2 回目の実行時shape.geometryCanvas.LayoutTransform
は、TransformGroup
2 つの要素の です。
(Xamlで宣言された)の参照geometryCanvas
は、画面で使用されているものではないようです。