2016-01-20 28 views
8

我正在基於TreeView創建可重用的自定義控件。我對定製控件創建在控制列,這樣的依賴項屬性:如何將樣式應用於自定義控件庫中的DependencyObject

public GridViewColumnCollection Columns 
    { 
     get { return (GridViewColumnCollection)GetValue(ColumnsProperty); } 
     set { SetValue(ColumnsProperty, value); } 
    } 

    public static readonly DependencyProperty ColumnsProperty = 
     DependencyProperty.Register("Columns", typeof(GridViewColumnCollection), typeof(TreeListView), new PropertyMetadata(new GridViewColumnCollection())); 

這讓我指定XAML一堆列。問題在於我需要第一列具有自定義單元格模板。我正要從GridViewColumn派生類,像這樣來處理這個:

public class TreeGridViewColumn : GridViewColumn 
{ 
} 

,然後給它在Generic.xaml自定義控制所需的樣式:

<Style TargetType="{x:Type local:TreeGridViewColumn}"> 
    <Setter Property="CellTemplate"> 
     <Setter.Value> 
      <DataTemplate> 
       <Border Background="Black" /> <!-- Just for example --> 
      </DataTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

然而,樣式從不應用於TreeGridViewColumn的實例。我知道,我可能需要添加:

DefaultStyleKeyProperty.OverrideMetadata(typeof(TreeGridViewColumn), new FrameworkPropertyMetadata(typeof(TreeGridViewColumn))); 

但是我不能這樣做,因爲的GridColumn基類是不是FrameworkObject,它是一個DependencyObject的。如何將樣式應用於自定義控件庫中定義的GridViewColumn的後代?

+1

您不能以任何方式將Style應用於GridViewColumn,因爲它不是FrameworkElement,因此也不是可風化的。它沒有Style屬性。 – Clemens

+0

@Clemens:正確。我想我可以在解決這個問題時做得更好 - 當我寫這個問題的時候 - 我正在嘗試創建一個GridViewColumn的衍生物,並根據我的需要重寫CellTemplate。我花了一些時間使用Reflector來查看DataGrid列如何執行此操作(即Text列等),看起來不幸的是,它們只是在代碼中手動創建默認模板。這對他們來說很好,因爲他們的模板只有一個或兩個框架元素。我的模板太複雜了,所以我需要找到另一條路線。 – user3690202

回答

1

像這樣想:TreeGridViewColumn應該是一個虛擬對象,它包含列本身的重要信息,例如寬度和高度,以及該列標題下的每個單元格,例如單元格模板本身。因此,不要嘗試從TreeGridViewColumn中創建FrameworkElement。這裏是一個例子,你可能最終使用TreeGridViewColumn。

 <TreeGridViewColumn Header="First Col" Width="50"> 
      <TreeGridViewColumn.CellTemplate> 
       <DataTemplate> 
        <Button> 
         click me 
        </Button> 
       </DataTemplate> 
      </TreeGridViewColumn.CellTemplate> 
     </TreeGridViewColumn> 

一旦你準備好,以顯示我建議你列和細胞通過調用它們的辦法來寫這與FrameworkElements涉及自己的自定義面板排列方式讓您定位列和單元格您想要的方式。你最終會在自定義面板類中做很多數學運算。這還意味着你最終會花費一個月的時間編程TreeGridView。我建議你選擇一個快捷方式並下載這樣的代碼。在線已經很少TreeListViews。只要看看他們的DLL,看看它是否會制定出你

編輯:

確定這裏是一個建議,你如何能夠解決您的問題。其只是一個建議

的DefaultTextColumnData類是一個虛擬對象保持所有必要的相關信息等的列寬度等

DataGridCellControl將是FrameworkElement的繪製單元。它是一個FrameworkElement,因此它將在generic.xaml資源字典中有一個定義的樣式。

總結DefaultTextColumnData將包含列本身的所有信息。 DataGridCellControl將是一個控件,如果您在該列中有20個單元格,則該控件最終可能擁有20個實例。

DataGridCellControl必須知道它的列。 這是DataGridCellControl的代碼怎麼看上去都差不多:

class DefaultTextColumnData : DataGridColumn 
{ 
} 

class ComplexColumnData : DataGridColumn 
{ 
} 

class DataGridCellControl : Control 
{ 
    public DataGridColumn Column 
    { 
    get; set; 
    } 

    public DataTemplate DefaultTextCellTemplate 
    { 
    get; set; 
    } 

    public override Size MeasureOverride(Size size) 
    { 
    ... 
    if(this.Column is DefaultTextColumnData) 
    { 
    this.Template = this.DefaultTextCellTemplate 
    } 

    if(this.Column is ComplexColumnData) 
    { 
    this.Template = ... 
    } 
    ... 
    return new Size(30, 30); 
    } 
} 

DefaultTextCellTemplate將在您的通用進行設置。xaml是這樣的:

<Style TargetType={x:Type DataGridCellControl}> 
<Setter Property="DefaultTextCellTemplate"> 
    <Setter.Value> 
    <DataTemplate> 
    <TextBlock Background="Black" Margin="5"/> 
    .... 

多數民衆贊成你如何設置默認單元格模板在您的資源字典。

+0

謝謝,但這部分我已經知道,並有工作。如果你在這個問題上查看我的其他建議 - 真正的問題是我有一個我想要專門化的列,並且有一個預先指定的單元格模板。類似於DataGrid爲文本,複選框,下拉列表等提供一系列預先配置的列。 – user3690202

+0

那是什麼單元格模板用於 –

+0

從上面複製,因爲我不會被重寫完全相同的事情:「我是試圖創建一個派生的GridViewColumn,並根據需要重寫CellTemplate。我花了一些時間使用Reflector來查看DataGrid列如何執行此操作(即Text列等),而且看起來很不幸,他們只是創建了默認值模板在代碼中是手動的,這對他們來說很好,因爲他們的模板只有一個或兩個框架元素,我的模板太複雜了,所以我需要找到另一個路徑。 – user3690202

相關問題