2011-02-02 38 views
5

Có cách nào để đặt thuộc tính được đính kèm qua Kiểu không?WPF: Tôi có thể xác định/đặt thuộc tính đính kèm thông qua một kiểu không?

Tôi có ví dụ: một nút trên đó Interaction thứ được thiết lập (từ System.Windows.Interactivity)

<Button> 
    <i:Interaction.Triggers> 
    ... 
    </i:Interaction.Triggers> 
</Button> 

Bây giờ tôi muốn thực hiện một phong cách, trong đó có bất động sản Interaction.Triggers được thiết lập, do đó thay thế dư thừa bằng cách để xác định tài sản đó trên mọi phiên bản Nút. Điều này có thể thực hiện được trong WPF không?

<Style Target={x:Type Button}> 
    <!-- ??? --> 
    <Setter PropertyName="i.Interaction.Triggers"> 
    ... 

Bằng cách nào đó tôi không thể xem như thế nào, nhưng tôi đã thấy những ví dụ khác trong web mà tài sản gắn liền dường như có thể truy cập từ bên trong một phong cách ...

Cập nhật

Vì vậy, về cơ bản đây là một vấn đề với Interaction.Triggers không có cách nào để "Set" một cái gì đó. Làm thế nào tôi có thể tái sử dụng một tập hợp các định nghĩa tương tác?

+0

thể trùng lặp: http://stackoverflow.com/questions/4067876/set-hidden-attachedproperty-through-style – flq

Trả lời

8

Đây là sự cố đã biết với thuộc tính thu thập chỉ đọc (điều tương tự với bộ sưu tập InputBindings). Để giải quyết vấn đề này tôi đã tạo ra một tài sản kèm theo:

public static StyleTriggerCollection GetTriggers(DependencyObject obj) { 
    return (StyleTriggerCollection)obj.GetValue(TriggersProperty); 
} 

public static void SetTriggers(DependencyObject obj, StyleTriggerCollection value) { 
    obj.SetValue(TriggersProperty, value); 
} 

public static readonly DependencyProperty TriggersProperty = 
    DependencyProperty.RegisterAttached("Triggers", typeof(StyleTriggerCollection), typeof(ControlExtensions), new UIPropertyMetadata(null, OnTriggersChanged)); 

static void OnTriggersChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { 
    var triggers = (StyleTriggerCollection) e.NewValue; 

    if (triggers != null) { 
     var existingTriggers = Interaction.GetTriggers(d); 

     foreach (var trigger in triggers) { 
      existingTriggers.Add((TriggerBase)trigger.Clone()); 
     } 
    } 
} 

Thuộc tính này sử dụng StyleTriggerCollection tùy chỉnh, bởi vì bộ sưu tập cò tiêu chuẩn có nhà xây dựng không được công khai:

public class StyleTriggerCollection : Collection<TriggerBase> 
{ 
} 

Trong setter Phong cách bạn có thể sử dụng nó như này:

<Setter Property="my:ControlExtensions.Triggers"> 
    <Setter.Value> 
     <my:StyleTriggerCollection> 
      <!-- Put your triggers here --> 
     </my:StyleTriggerCollection> 
    </Setter.Value> 
</Setter> 
+0

Điều đó có vẻ rất hứa hẹn, tôi sẽ hav e một cái nhìn ngay sau khi tôi trở lại trên mã! – flq

+1

Điều này dường như làm việc, nhưng tôi bối rối khi sử dụng một DataContext trong trình kích hoạt tthe. Tôi dường như không thể lấy RelativeSource AncestorType ... để làm việc ... – flq

+0

Bạn cần hiểu cách hoạt động của nguồn tương đối. Nó hoạt động trên các yếu tố có trong cây thị giác. Tôi trường hợp này các kích hoạt không có trong bộ sưu tập cây trực quan - bộ kích hoạt chỉ là một thuộc tính của một phần tử trong cây trực quan. Lý do tại sao dữ liệu kế thừa kế thừa hoạt động trong trường hợp này là Triggers kế thừa Freezable. Bạn có thể đọc về nó ở đây: http://drwpf.com/blog/category/freezables/ –

Các vấn đề liên quan