2009-04-02 31 views
8

DataTemplate mặc định trong ứng dụng wpf hiển thị kết quả của phương thức .ToString(). Tôi đang phát triển một ứng dụng mà DataTemplate mặc định sẽ không hiển thị gì cả.Chỉ định DataTemplate trống mặc định thay vì mặc định 'ToString()' DataTemplate

Tôi đã thử:

<Grid.Resources> 
    <DataTemplate DataType="{x:Type System:Object}"> 
    <Grid></Grid> 
    </DataTemplate> 
</Grid.Resources> 

Nhưng điều này không làm việc. Có ai biết nếu điều này là có thể mà không specifiing một DataTemplate cụ thể cho mọi loại lớp trong ứng dụng?

Trả lời

4

Tôi biết không có cách nào để thực hiện việc này. Theo nhận xét của Joe bên dưới, WPF đặc biệt không cho phép chỉ định một số DataTemplate cho loại Object.

Tùy thuộc vào yêu cầu chính xác của bạn, việc tìm kiếm DataTemplate phù hợp với loại cụ thể có thể dễ dàng hơn. Nếu bạn tìm thấy, hãy sử dụng nó. Nếu không, không hiển thị gì cả. Ví dụ:

<ContentControl Content="{Binding YourContent}" ContentTemplateSelector="{StaticResource MyContentTemplateSelector}"/> 

Và trong chọn của bạn (pseudo-code, rõ ràng):

var dataTemplateKey = new DataTemplateKey() { DataType = theType; }; 
var dataTemplate = yourControl.FindResource(dataTemplateKey); 

if (dataTemplate != null) 
{ 
    return dataTemplate; 
} 

return NulloDataTemplate; 
+2

"WPF phù hợp với một đối tượng với DataTemplate của mình bằng kiểu thời gian chạy chính xác" - Không đúng. Nếu bạn thêm một DataTemplate với DataType = BaseClass, nó sẽ khớp với SubClass. Tôi đã nhìn thấy nó hoạt động. Thật không may, khung công tác đặc biệt không cho phép tạo một DataTemplate cho System.Object; bạn nhận được một lỗi thời gian chạy "Các loại 'DataTemplateKey' không xây dựng. DataTemplate.DataType không thể được loại đối tượng." –

+0

Bạn nói đúng. Tôi đã nghĩ về phong cách, mà không phải là tự động kế thừa. Cập nhật câu trả lời của tôi. Cảm ơn. –

1

Tôi không chắc chắn về thay thế mặc định DataTemplate, nhưng bạn có thể sử dụng một ValueConverter để vượt qua màn ToString trong trường hợp của một số loại và một chuỗi rỗng khác. Dưới đây là một số mã (lưu ý rằng các doesnt typeb TextBlock có bộ chuyển đổi vào nó để hiển thị những gì nó trông giống như bình thường):

.xaml:

<Window x:Class="EmptyTemplate.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:loc="clr-namespace:EmptyTemplate" 
    Title="Window1" Height="300" Width="300"> 
    <Window.Resources> 
     <loc:AType x:Key="atype"/> 
     <loc:BType x:Key="btype"/> 
     <loc:TypeConverter x:Key="TypeConverter"/> 
    </Window.Resources> 
    <StackPanel> 
     <Button Content="{Binding Source={StaticResource atype}, Converter={StaticResource TypeConverter}}"/> 
     <Button Content="{Binding Source={StaticResource btype}, Converter={StaticResource TypeConverter}}"/> 
     <TextBlock Text="{Binding Source={StaticResource atype}, Converter={StaticResource TypeConverter}}"/> 
     <TextBlock Text="{Binding Source={StaticResource btype}}"/> 
    </StackPanel> 
</Window> 

.xaml.cs:

namespace EmptyTemplate 
{ 
    /// <summary> 
    /// Interaction logic for Window1.xaml 
    /// </summary> 
    public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 
     } 
    } 

    public class AType { } 

    public class BType { } 

    public class TypeConverter : IValueConverter 
    { 
     public DataTemplate DefaultTemplate { get; set; } 

     #region IValueConverter Members 

     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      if (value.GetType() == typeof(AType)) 
      { 
       return value.ToString(); 
      } 
      return DefaultTemplate; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 

     #endregion 
    } 
} 
4

Nếu bạn đang sử dụng mẫu MVVM và có lớp trừu tượng mà tất cả các lớp ViewModel của bạn lấy được từ đó, bạn có thể sử dụng lớp đó thay vì System.Object:

<Grid.Resources> 
    <DataTemplate DataType="{x:Type vm:VMBase}"> 
    </DataTemplate> 
</Grid.Resources> 
+2

Bạn vừa mới cứu mạng tôi. Dĩ nhiên là không đúng, nhưng đây chính xác là những gì tôi đang tìm kiếm – Firedragon

2

Tôi đã sử dụng Nullable, làm việc cho tình huống của tôi.

<DataTemplate DataType="{x:Type sys:Nullable}"> 
<!-- Content --> 
</DataTemplate> 
0

Dưới đây là một ví dụ làm việc về làm thế nào để làm điều này bằng cách sử dụng selector (cách tốt nhất IMO):

public class EmptyDefaultDataTemplateSelector : DataTemplateSelector 
{ 
    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     if (item != null) 
     { 
      var dataTemplateKey = new DataTemplateKey(item.GetType()); 
      var dataTemplate = ((FrameworkElement) container).TryFindResource(dataTemplateKey); 
      if (dataTemplate != null) 
       return (DataTemplate) dataTemplate; 
     } 

     return new DataTemplate(); //null does not work 
    } 
} 
Các vấn đề liên quan