2012-04-15 4 views
4

DataGrid에서 CellTemplateCellEditingTemplate을 사용합니다. 두 DataTemplates FrameworkElement.IsLoaded Property에서 TextBlock을 볼 수있는 경우에도 False을 반환하고 및 Focus()을 호출하면 True이 반환됩니다.TextBox.IsLoaded가 표시되면 False를 반환합니다.

이것은 버그입니까? 또는 누군가가 설명 할 수 있습니까?이 행동의 이유는 무엇입니까?


나는 데모 목적으로이 샘플 응용 프로그램을 만들었습니다. IsLoaded 표시는 종속성 속성이 아니기 때문에

MainWindow.xaml.cs를

namespace WpfApplication 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 

      this.DataContext = new List<string> { "Row1", "Row2" }; 
     } 
    } 

    public class FocusAttached 
    { 
     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(MainWindow), new UIPropertyMetadata(false, IsFocusedChanged)); 

     static void IsFocusedChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
     { 
      FrameworkElement element = obj as FrameworkElement; 

      if ((bool)e.NewValue) 
      { 
       Console.Write(element); 
       Console.Write(" IsLoaded=" + element.IsLoaded); 
       Console.Write(" IsVisible=" + element.IsVisible); 
       Console.Write(" Focusable=" + element.Focusable); 
       // here I call Focus() 
       Console.Write(" Focus() returns:" + element.Focus()); 
       Console.WriteLine(" IsLoaded=" + element.IsLoaded); 
      } 
     } 
    } 
} 

MainWindow.xaml 모든

<Window x:Class="WpfApplication.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:c="clr-namespace:WpfApplication" 
     Title="Please click on row!" SizeToContent="WidthAndHeight"> 
    <DataGrid ItemsSource="{Binding}" AutoGenerateColumns="False"> 
     <DataGrid.Columns> 
      <DataGridTemplateColumn> 
       <DataGridTemplateColumn.CellTemplate> 
        <DataTemplate> 
         <TextBlock Text="{Binding IsLoaded, RelativeSource={RelativeSource Self}, Mode=OneWay, 
                StringFormat='TextBlock in CellTemplate: IsLoaded={0}'}" /> 
        </DataTemplate> 
       </DataGridTemplateColumn.CellTemplate> 

       <DataGridTemplateColumn.CellEditingTemplate> 
        <DataTemplate> 
         <TextBox c:FocusAttached.IsFocused="True" 
           Text="{Binding IsLoaded, RelativeSource={RelativeSource Self}, Mode=OneWay, 
               StringFormat='Even after call Focus(): IsLoaded={0}'}" />          
        </DataTemplate> 
       </DataGridTemplateColumn.CellEditingTemplate> 
      </DataGridTemplateColumn> 
     </DataGrid.Columns> 

     <DataGrid.CellStyle> 
      <Style TargetType="DataGridCell"> 
       <Setter Property="Focusable" Value="False" /> 
       <Style.Triggers> 
        <Trigger Property="IsSelected" Value="True"> 
         <Setter Property="IsEditing" Value="True" /> 
        </Trigger> 
       </Style.Triggers> 
      </Style>    
     </DataGrid.CellStyle> 
    </DataGrid> 
</Window> 

답변

1

첫째, 당신의 바인딩은, 쓸모. 알림이 없으며 텍스트가 변경되지 않았습니다.

IsLoaded는 측정 및 배열과 같이 지연되므로 false입니다. 요소는 포커스 가능, 가시성 및 사용 가능하므로 집중 될 수 있습니다. 그러나이 시점에서 이미 측정되고 렌더링 된 요소에 대한 보장은 없습니다. 이 조치는 Dispatcher에 대기 중입니다. 처리가 완료되면 IsLoaded가 true가됩니다. 이것을 시도하십시오 :

static void IsFocusedChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
{ 
    FrameworkElement element = obj as FrameworkElement; 

    if ((bool)e.NewValue) 
    { 
     Console.Write(element); 
     Console.Write(" IsLoaded=" + element.IsLoaded); 
     Console.Write(" IsVisible=" + element.IsVisible); 
     Console.Write(" Focusable=" + element.Focusable); 
     // here I call Focus() 
     Console.Write(" Focus() returns:" + element.Focus()); 
     element.Dispatcher.BeginInvoke((Action)(() => 
      { 
       Console.WriteLine(" IsLoaded=" + element.IsLoaded); 
      }), 
      System.Windows.Threading.DispatcherPriority.Loaded); 
    } 
} 
+0

그렇다면 IsLoaded는 True이고 Binding에 대한 귀하의 권리입니다. 그러나 이것은 아직 프리젠 테이션 엔진에 통합되지 않았거나 (아니면 결코) 통합되지 않은 요소를 집중시킬 수 있음을 의미합니다 ('IsLoaded = True')? 그리고'IsVisible = True'는 진정으로 요소를 볼 수 있다는 것을 의미하지 않습니까? – LPL

+0

여기서 문제는 다른 프로세스를 다른 성질과 비교하려고한다는 것입니다. IsLoaded는 포커스가 응용 프로그램 논리의 일부인 동안 측정/정렬/렌더링 메커니즘의 일부입니다. 요소가 포커스에 유효합니까? 예, 사용 가능하고 보이기 때문에 PresentationSource에 첨부됩니다 (템플릿이 실현 되었기 때문에). 요소가 이미로드되어 있습니까? 아직은 아니지만 PresentationSource에 첨부되어 있기 때문에 가능합니다. –

관련 문제