2015-07-13 3 views
0

Я использую это расширение this toolkit, он автоматически добавляет TextBox в начало каждого столбца DataGrid для фильтрации из следующего кода.Как создать автоматически сгенерированные элементы в xaml

<DataGrid ColumnHeaderStyle="{StaticResource {ComponentResourceKey 
     TypeInTargetAssembly={x:Type filter:DataGridHeaderFilterControl}, 
     ResourceId=DataGridHeaderFilterControlStyle}}" > 

Однако добавленный заголовок столбца и текстовые поля имеют другой стиль, чем я хочу.

Поэтому я могу сделать это, чтобы создать заголовок столбца, но он не изменит текстовые поля.

<Style x:Key="FilterHeader" 
     BasedOn="{StaticResource {ComponentResourceKey TypeInTargetAssembly={x:Type filter:DataGridHeaderFilterControl}, 
                 ResourceId=DataGridHeaderFilterControlStyle}}" 
     TargetType="{x:Type DataGridColumnHeader}"> 

    <Setter Property="Foreground" Value="Blue" /> 

</Style> 

... 

<DataGrid ColumnHeaderStyle="{DynamicResource FilterHeader}"> 

Я попытался положить это в Window.Resources, чтобы увидеть, если он имел влияние на текстовые поля. Он изменил мои другие текстовые поля, это не влияет на текстовые поля, созданные расширением.

<Style TargetType="TextBox"> 
    <Setter Property="Foreground" Value="Blue" /> 
</Style> 

Но не кубики. Единственное, что я нашел, это то, что работает:

public void DataGrid_OnLoad(object sender, RoutedEventArgs e) 
    { 
     IEnumerable<System.Windows.Controls.TextBox> collection = 
      FindVisualChildren<System.Windows.Controls.TextBox>(TitleBar); 

     foreach (System.Windows.Controls.TextBox tb in collection) 
     { 
      tb.Foreground = Brushes.Blue; 
     } 
    } 

    public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject 
    { 
     if (depObj != null) 
     { 
      for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) 
      { 
       DependencyObject child = VisualTreeHelper.GetChild(depObj, i); 
       if (child != null && child is T) 
       { 
        yield return (T)child; 
       } 

       foreach (T childOfChild in FindVisualChildren<T>(child)) 
       { 
        yield return childOfChild; 
       } 
      } 
     } 
    } 

Но это похоже на мусорный способ сделать это. Как я могу сделать это исключительно в xaml или, по крайней мере, более чисто в C#?

ответ

1

Просмотрев исходный код, я заметил, что TextBox на самом деле не текстовое поле, а подкласс текстового поля. DelayTextBox

Таким образом, вы можете просто изменить свой стиль, чтобы нацелить его вместо этого.

<Style TargetType="DelayTextBox"> 
    <Setter Property="Foreground" Value="Blue" /> 
</Style> 

Я не пробовал, но он должен работать.

Update

Наконец нашел проблему. Стили должны быть определены в стиле их родителя.

<Style TargetType="{x:Type filter:DataGridColumnFilter}"> 
    <Style.Resources> 

     <Style TargetType="{x:Type support:DelayTextBox}"> 
      <Setter Property="Foreground" Value="Blue" /> 
      <Setter Property="FontWeight" Value="Bold"/> 
     </Style> 

     <Style TargetType="{x:Type ComboBox}"> 
      <Setter Property="Foreground" Value="Blue" /> 
      <Setter Property="FontWeight" Value="Bold"/> 
     </Style> 
    </Style.Resources> 
</Style> 

Я добавил comboxbox, так как предполагаю, что вы тоже этого захотите. вы можете вытащить сеттер для смелых по мере необходимости .. использовал его для тестирования.

+0

Мне пришлось изменить его на '