2009-05-27 28 views
5

Tôi đang tạo UserControl của riêng mình và tôi có hai DataTemplates khác nhau theo phần UserControl.Resources trong XAML của tôi. Tôi muốn lựa chọn giữa hai datatemplates tùy thuộc vào giá trị của một tài sản trên các đối tượng được hiển thị trong một listview. Tôi làm điều này bằng cách tạo một lớp tùy chỉnh DataTemplateSelector và ghi đè phương thức SelectTemplate được cho là trả về DataTemplate mà tôi muốn sử dụng. Tuy nhiên, tôi không có ý tưởng làm thế nào để "tìm" datatemplates của tôi được đặt trong phần tài nguyên UserControls, tất cả các ví dụ tôi đã nhìn thấy chỉ lấy datatemplates từ Window.Resources. Trong ví dụ này, họ lấy hiện tại MainWindow và sau đó sử dụng FindResource để tìm DataTemplate, làm thế nào để tôi lấy tôi UserControl một cách tương tự ?:Cách tìm tài nguyên trong UserControl từ lớp DataTemplateSelector trong WPF?


public override DataTemplate 
      SelectTemplate(object item, DependencyObject container) 
     { 
      if (item != null && item is AuctionItem) 
      { 
       AuctionItem auctionItem = item as AuctionItem; 
       Window window = Application.Current.MainWindow; 

       switch (auctionItem.SpecialFeatures) 
       { 
        case SpecialFeatures.None: 
         return 
          window.FindResource("AuctionItem_None") 
          as DataTemplate; 
        case SpecialFeatures.Color: 
         return 
          window.FindResource("AuctionItem_Color") 
          as DataTemplate; 
       } 
      } 

      return null; 
     } 

Ví dụ trên là từ đây : ItemsControl.ItemTemplateSelector Property

Trả lời

6

Tôi thường khởi tạo DataTemplateSelector của mình từ mã phía sau với UserControl làm tham số trong hàm tạo của DataTemplateSelector, như sau:

public class MyUserControl : UserControl 
{ 
    public MyUserControl() 
    { 
     Resources["MyDataTemplateSelector"] = new MyDataTemplateSelector(this); 
     InitializeComponent(); 
    } 
} 

public class MyDataTemplateSelector : DataTemplateSelector 
{ 
    private MyUserControl parent; 
    public MyDataTemplateSelector(MyUserControl parent) 
    { 
     this.parent = parent; 
    } 

    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     parent.DoStuff(); 
    } 
} 

Không phải là cô gái xinh đẹp nhất nhất trong thành phố, nhưng nó được công việc làm;)

Hope this helps!

+1

Không có cách nào để làm điều tương tự trong XAML? – Joakim

+0

Ok điều này hoạt động tốt ... Nhưng nó sẽ được tốt đẹp để biết những gì được đề nghị cách làm điều này là, tốt nhất là làm tất cả trong XAML. – Joakim

+0

Vì vậy, sự thật .. Tôi cũng muốn biết một cách đẹp hơn .. nhưng tôi không nghĩ rằng vấn đề này có thể được giải quyết với XAML thực sự. Bạn sẽ cần một số loại tài liệu tham khảo trong mã của bạn phía sau, vì vậy cách dễ nhất là chỉ cần cung cấp trực tiếp;) – Arcturus

2
 <DataTemplate x:Key="addTemplate"> 
     <Button Command="{Binding Path=AddCommand}">Add</Button> 
    </DataTemplate> 

    <DataTemplate x:Key="editTemplate"> 
     <Button Command="{Binding Path=UpdateCommand}">Update</Button> 
    </DataTemplate> 

    <TemplateSelectors:AddEditTemplateSelector 
     AddTemplate="{StaticResource addTemplate}" 
     EditTemplate="{StaticResource editTemplate}" 
     x:Key="addEditTemplateSelector" /> 

XAML chỉ!

6

Hãy thử điều này:

public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     if (item != null && item is AuctionItem) 
     { 
      AuctionItem auctionItem = item as AuctionItem; 

      switch (auctionItem.SpecialFeatures) 
      { 
       case SpecialFeatures.None: 
        return 
         ((FrameworkElement)container).FindResource("AuctionItem_None") 
         as DataTemplate; 
       case SpecialFeatures.Color: 
        return 
         ((FrameworkElement)container).FindResource("AuctionItem_Color") 
         as DataTemplate; 
      } 
     } 

     return null; 
    } 
0

Một WinRT & giải pháp Windows Phone bao gồm di chuyển lên cây thị giác cho đến khi phụ huynh kiểm soát được tìm thấy:

protected override Windows.UI.Xaml.DataTemplate SelectTemplateCore(object item, Windows.UI.Xaml.DependencyObject container) 
    { 
     var parent = FindParent<MyParentControlType>(container as FrameworkElement); 

     if(parent != null) 
     { 
      if (item is Something) 
       return parent.Resources["TemplateForSomething"] as DataTemplate; 
      else if(item is SomethingElse) 
       return parent.Resources["TemplateForSomethingElse"] as DataTemplate; 
      else 
       // etc 
     } 
     else 
     { 
      return App.Current.Resources["SomeFallbackResource"] as DataTemplate; 
     } 
    } 

    public static T FindParent<T>(FrameworkElement element) where T : FrameworkElement 
    { 
     FrameworkElement parent = Windows.UI.Xaml.Media.VisualTreeHelper.GetParent(element) as FrameworkElement; 

     while (parent != null) 
     { 
      T correctlyTyped = parent as T; 

      if (correctlyTyped != null) 
       return correctlyTyped; 
      else 
       return FindParent<T>(parent); 
     } 

     return null; 
    } 

Phương pháp FindParent được dựa trên câu trả lời được chấp nhận ở đây : How to get a ListView from a ListViewItem?

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