2012-04-15 70 views
4

DataGrid中,我使用CellTemplateCellEditingTemplate。在兩個數據模板FrameworkElement.IsLoaded Property返回False即使我可以看到TextBlock,使用TextBoxFocus()調用已返回TrueTextBox.IsLoaded在可見後返回False

這是一個錯誤?或者有人可以解釋,這種行爲的原因是什麼?


我創建了此示例應用程序用於演示目的。

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不是一個依賴項屬性。沒有通知,文字沒有變化。

IsLoaded是錯誤的,因爲它像延遲測量和排列一樣延遲。元素是可調焦的,可見的和啓用的,因此可以集中。但是不能保證這個元素已經在這個時候測量和渲染了。這些操作在分派器中排隊。當他們被處理時,IsLoaded將是真實的。試試這個:

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是真的,你的權利關於綁定。但是這意味着即使它尚未(或可能永遠不會)集成到演示文稿引擎中(「IsLoaded = True」),您仍可以集中某個元素?而'IsVisible = True'並不意味着你可以真正看到這個元素? – LPL 2012-04-16 12:05:00

+0

這裏的麻煩在於你試圖比較不同性質的不同過程。 IsLoaded是度量/排列/渲染機制的一部分,而焦點是應用程序邏輯的一部分。該元素是否適用於焦點?是的,因爲它已啓用且可見,並且已附加到PresentationSource(因爲模板已實現)。元素是否已經加載?還沒有,但它會,因爲它附加到PresentationSource。 – 2012-04-16 12:31:41