2012-09-24 3 views
0

내 바인딩. 그래서 시각적 설정과 레이블 텍스트가 코드 숨김 파일의 속성에 바인딩XamlReader 구문 분석 후 바인딩 복원 내 문제는 다음과 같습니다. 사용자가 셰이프 (클래스 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> 

: 그리기 모양은 누적 경로와 라벨을 캡슐화합니다.

이 그리기 셰이프를 사용하여 Canvas를 deserialize 한 후에는 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()을 추가 한 : 코드의 다른 부분을 보면 편집

2012년 9월 25일 어떤 통찰력

에 대한 Bindings not applied to dynamically-loaded xaml

감사를 많이하는 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에 선언 됨)에 대한 참조가 화면에 사용 된 것이 아닙니다.

답변

1

알 수 있습니다.

역 직렬화 후 코드 숨김 파일 외부에서 x : Name의 XAML 요소를 성공적으로 참조 할 수 없다는 것을 알지 못했습니다.

해결책은 예를 들어, UserControl을에 FindName()을 사용하는 것입니다

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); 

은 훨씬 단순하고 우아한 soluti처럼 작동합니다. 와 dbaseman에 의해 제안에 :

shape.DataContext = this; 

희망이 다른 사람이

:-) 내 실수를 방지하는 데 도움이