2017-03-07 2 views
1

나는 며칠 동안 이걸로 고생했다. Google은 도움이되지 않는다.잃어버린 초점의 수수께끼 - 붙인 행동에서 요소를 집중시킬 수 없다

InkCanvas로 장식 된 RichTextBox가 있습니다. 뇌졸중은 InkCanvas에서 수집되고 인식됩니다. adorner가 닫히면 RichTextBox의 연결된 동작이 명시 적으로 RichTextBox로 포커스를 강제로 이동하는 데 사용됩니다. 그러나 RichTextBox에 포커스를 명시 적으로 호출 했음에도 불구하고 RichTextBox는 신호를 수신하지 못합니다.

어떻게 될까요? 어떻게 수정합니까?

TIA

XAML

 <ScrollViewer Grid.Row ="2" Grid.Column="1" VerticalScrollBarVisibility="Auto" > 
      <!--ScrollViewer can only have one child.--> 
      <Grid> 

     ........................................ 

<!-- 
        XAML that creates the adorned control and the adorner 
       --> 
       <ac:AdornedControl IsAdornerVisible="{Binding TranscriptionLayer.IsAdornerVisible}" Grid.ColumnSpan="2"> 
        <!--#region Adorned Element--> 
        <!-- 
         TranscriptionLayer will have an Adorner (inkcanvas) for handwriting recogntion. 
         The RichTextBox is the element being adorned and sets the size of the adornment object (i.e., 
         the inkcanvas writing surface). The RichTextControl holds the actual transcript. 
        --> 
        <RichTextBox x:Name="RichTextControl" Panel.ZIndex="{Binding TranscriptionLayer.ZIndex}" 
           Height="{Binding VirtualPage.Height}" 
           Visibility="{Binding TranscriptionLayer.TranscriptIsVisible}" 
          SpellCheck.IsEnabled="True" 
          VerticalScrollBarVisibility="Auto" 
          AcceptsReturn="True" AcceptsTab="True" 
          > 
         <!--Remove blank line between paragraphs--> 
         <RichTextBox.Resources> 
          <Style TargetType="{x:Type Paragraph}"> 
           <Setter Property="Margin" Value="0"/> 
          </Style> 
         </RichTextBox.Resources> 

         <i:Interaction.Behaviors> 
          <!--Update the menu and toolbar when a selection is made in the RichTextBox--> 
          <!--The behavior is bound to the SelectionChanged of the RichTextBox. 
          <b:RichTextBehavior AlignLeft ="{Binding TranscriptionLayer.AlignLeft}" /> --> 
          <b:RichTextBehavior 
           FontHeight="{Binding ElementName=Fontheight, Path=SelectedItem, Mode=TwoWay, Converter={c:NullToDoubleConverter}}" 
           TextFont="{Binding ElementName=Fonttype,  Path=SelectedItem}" 
           TextBold="{Binding ElementName=ToggleBold, Path=IsChecked}" 
           Italic="{Binding ElementName=ToggleItalic, Path=IsChecked}" 
           Underline="{Binding ElementName=ToggleUnderline, Path=IsChecked}" 
           Strikethrough="{Binding ElementName=ToggleStrikethrough, Path=IsChecked}" 
           ParagraphTag ="{Binding ElementName=CurrentParagraph, Path=SelectedItem}" 
           SelectedText="{Binding TranscriptionLayer.SelectedText}" 
           IsFocused ="{Binding TranscriptionLayer.RichTextHasFocus}" 
          /> 
         </i:Interaction.Behaviors> 

        </RichTextBox> 


        <!--#endregion--> 
        <ac:AdornedControl.AdornerContent> 
         <!--#region The Adorner--> 
         <!-- This is the framework element as the adorner content. It is always on top of the adorned element. There adorned elements 
          is the RichTextConttrol. 
          The ItemsControl will expand to the width of the parent adorner which takes its size from the adorned element-the 
          RichTextConttrol. The ItemsControl inherits from  System.Windows.FrameworkElement. 
         --> 

          <ItemsControl x:Name="WritingLayerControl" ItemsSource="{Binding TranscriptionLayer.WritingBoxes}" > 
           <!-- 
           If the <ItemsControl.ItemsPanel> is not used, the ItemsControl will default to a vertical StackPanel. 
          --> 

           <ItemsControl.ItemTemplate> 
            <!-- 
           DataTemplate and DataType point to a class, not a namespace! 
          --> 
            <DataTemplate DataType="{x:Type vm:WritingBoxViewModel}" > 
             <Grid> 
              <Grid.RowDefinitions> 
               <!-- 0 to be used for recogntion results--> 
               <RowDefinition Height="auto" /> 
               <!-- 1 to be used for Ink --> 
               <RowDefinition Height="auto"/> 
              </Grid.RowDefinitions> 

              <TextBlock Grid.Row="0" Text="{Binding RecognitionResults}" Background="#100000FF" 
                Height="{Binding RecognitionResultsHeight}"/> 

              <!--  
            Binding Mode must be set to TwoWay on TheSelectedStrokes because by default binding works one way, 
            i.e. loading changes from the view model, but not updating the viewmodel back. So either use: 
            TheSelectedStrokes="{Binding SelectedStrokes, Mode=TwoWay}" or set it with 
            FrameworkPropertyMetadataOptions.BindsTwoWayByDefault in TheSelectedStrokes dependency definition. 

            Background is of type Brush, so must use ImageBrush, DrawingBrush, VisualBrush. 
            --> 

              <InkCanvas x:Name="InkCanvas" Grid.Row="1" 
             Height="{Binding WritingBoxHeight}" Strokes="{Binding Strokes}" 
             EditingMode="{Binding EditingMode}" 
             DefaultDrawingAttributes="{Binding DefaultDrawingAttributes}" > 

               <i:Interaction.Behaviors> 
                <b:InkCanvasBehavior DeletedStrokes="{Binding DrawingLayer.DeleteStrokes}" /> 
               </i:Interaction.Behaviors> 

               <InkCanvas.Background> 
                <!-- 
             Note: Making the DrawingBrush a StaticResource makes the XAML much more efficient as only one object 
              is created. It also is only created on the first pass and no update from the Bindings will happen so 
              the lines will not change even when the TypeSize is changed. 

             Viewport (type Rect) gives the position, width, and height of the base tile 
             --> 
                <DrawingBrush Stretch="Uniform" TileMode="Tile" Viewport="{Binding ViewPortBaseTile}" ViewportUnits="Absolute" > 
                 <DrawingBrush.Drawing> 
                  <GeometryDrawing> 
                   <GeometryDrawing.Geometry> 
                    <GeometryGroup> 
                     <!-- 
                  X is horizontal displacement from origin. 
                   Y is veritcal displacyement from origin. 
                   Origin O(0,0) is top-left of InkCanvas. 
                  --> 

                     <!-- Vertical Line 
                   <LineGeometry StartPoint="0,0" EndPoint="{Binding TileBottom}"/> 
                  --> 
                     <!-- Midline. Horizontal Line --> 
                     <LineGeometry StartPoint="{Binding MidLineStartPoint}" EndPoint="{Binding MidLineEndPoint}"/> 

                     <!-- BaseLine. Horizontal Line--> 
                     <LineGeometry StartPoint="{Binding BaseLineStartPoint}" EndPoint="{Binding BaseLineEndPoint}"/> 
                    </GeometryGroup> 

                   </GeometryDrawing.Geometry> 
                   <GeometryDrawing.Pen> 
                    <Pen Thickness="1" Brush="Tomato"/> 
                   </GeometryDrawing.Pen> 

                  </GeometryDrawing> 
                 </DrawingBrush.Drawing> 
                </DrawingBrush> 
               </InkCanvas.Background> 
              </InkCanvas> 

             </Grid> 
            </DataTemplate> 
           </ItemsControl.ItemTemplate> 
          </ItemsControl> 

         <!--#endregion--> 
        </ac:AdornedControl.AdornerContent> 
       </ac:AdornedControl> 
      </Grid> 
     </ScrollViewer> 

C#

namespace Behaviors 
{ 
    public class RichTextBehavior : Behavior<RichTextBox> 
    { 
     protected override void OnAttached() 
     { 
      base.OnAttached(); 
      AssociatedObject.SelectionChanged += RichTextBoxSelectionChanged; 
      AssociatedObject.TextChanged += RichTextBoxTextChanged; 
     } 

     protected override void OnDetaching() 
     { 
      base.OnDetaching(); 
      AssociatedObject.SelectionChanged -= RichTextBoxSelectionChanged; 
      AssociatedObject.TextChanged -= RichTextBoxTextChanged; 
     } 

.................................................... 

public static bool GetIsFocused(DependencyObject obj) 
     { 
      return (bool)obj.GetValue(IsFocusedProperty); 
     } 

     public static void SetIsFocused(DependencyObject obj, bool value) 
     { 
      obj.SetValue(IsFocusedProperty, value); 
     } 

     public static readonly DependencyProperty IsFocusedProperty = 
      DependencyProperty.RegisterAttached(
       "IsFocused", typeof(bool), typeof(RichTextBehavior), 
       new UIPropertyMetadata(false, OnIsFocusedPropertyChanged)); 

     private static void OnIsFocusedPropertyChanged(
      DependencyObject d, 
      DependencyPropertyChangedEventArgs e) 
     { 
      var behavior = d as RichTextBehavior; 

      var uie = (UIElement)behavior.AssociatedObject; 
      if ((bool)e.NewValue) 
      { 
       uie.Focus(); // Don't care about false values. 
      } 
     } 

마지막 라인 uie.Focus (

) 정확하게 실제 제어에 도달하지 않는다 - 그러나 RichTextBoxControl로 확인 !

코드 숨김 "의 GotFocus()"에 의해 입증되는 이벤트가 호출되고 있지 않습니다 :

코드 숨김

public partial class ProgressNotesView : UserControl 
    { 
     public ProgressNotesView() 
     { 
      InitializeComponent(); 
      RichTextControl.GotFocus += RichTextControl_GotFocus; 
      RichTextControl.LostFocus += RichTextControl_LostFocus; 

      Loaded += (s, e) => 
      { 
       // When used as a UserControl as Data first, the DataContext has already been set to the ViewModel 
       // before the UserControl is Initialized. 
       vm = (ProgressNoteViewModel)DataContext; 
       Fontheight.SelectedItem = 12.0; 
      }; 
     } 

     private void RichTextControl_LostFocus(object sender, RoutedEventArgs e) 
     { 
      var y = 10; 
     } 

     private void RichTextControl_GotFocus(object sender, RoutedEventArgs e) 
     { 
      var x = 10; 
     } 

그래서 마법은 초점을 반환 할 필요가 RichTextControl 내가 Adorner에서 InkCanvas 사용을 마쳤습니까?

정말 대단히 감사 드리며 (대머리가되기 전에)! TIA

+1

(''uie.Focus();'')가 실행되지만 false를 반환하거나 앱이이 부분에 도달하지 않는다는 것을 의미합니까? 또한''Keyboard.focus (uie)''를 사용하여 결과를 알려주십시오. 감사. – Ron

+0

@Ron 위의 코드에서 코드 숨김은 GotFocus 이벤트가 호출되지 않는 것처럼 포커스를받지 못했습니다. 이것은 uie.Focus()가 실행되고 있음에도 불구하고 RichTextBox로 올바르게 해결되었습니다. 나는 나의 문제를 발견했다. 감사. –

답변

0

나는 (I 포커스 이벤트를 찾을 수 없습니다) 많은 행운없이 Snoop 2.8.0를 사용했습니다. 그러나, uie.Focus() 호출 arround를 여러 지점에서

UIElement elementWithFocus = Keyboard.FocusedElement as UIElement; 

을 배치 빠르게에서 ScrollViewer가 초점이 아니라하여 RichTextBox을받는 것으로 나타났다. 추가 연구에 따르면 uie.Focus() 호출시 RichTextBox Visibility가 Hidden으로 설정되었습니다.

uie.Focus()를 호출하기 전에 RichTextBox 가시성이 Visible로 설정되었는지 확인하여 모든 문제를 해결했습니다.

교훈 : 분명히 요소가 포커스를 받기 전에 표시되어야합니다!