2009-10-30 27 views
34

Có cách nào để so sánh về loại đối tượng cho trình kích hoạt không?Trình kích hoạt WPF dựa trên loại đối tượng

<DataTrigger Binding="{Binding SelectedItem}" Value="SelectedItem's Type"> 
</DataTrigger> 

Bối cảnh: Tôi có nút Thanh công cụ và nút Ẩn tùy thuộc vào lớp con hiện được đặt cho đối tượng mục đã chọn.

Cảm ơn

Trả lời

29

Tại sao không chỉ sử dụng trình biến đổi lấy đối tượng và trả về một chuỗi loại đối tượng?

Binding="{Binding SelectedItem, Converter={StaticResource ObjectToTypeString}}"

và xác định chuyển đổi như:

public class ObjectToTypeStringConverter : IValueConverter 
{ 
    public object Convert(
    object value, Type targetType, 
    object parameter, System.Globalization.CultureInfo culture) 
    { 
     return value.GetType().Name;    
    } 

    public object ConvertBack(
    object value, Type targetType, 
    object parameter, System.Globalization.CultureInfo culture) 
    { 
     // I don't think you'll need this 
     throw new Exception("Can't convert back"); 
    } 
} 

Bạn sẽ cần phải khai báo tài nguyên tĩnh nơi nào đó trong XAML của bạn:

<Window.Resources> 
    <convs:ObjectToTypeStringConverter x:Key="ObjectToTypeString" /> 
</Window.Resources> 

đâu CONVS 'trong trường hợp này là không gian tên nơi trình chuyển đổi.

Hy vọng điều này sẽ hữu ích.

+10

+1 cho ý tưởng chung, tuy nhiên trình biến đổi phải trả về đối tượng Loại thay vì tên của nó ... –

+2

Điều đó có hiệu quả không? Sẽ không phải là thời gian chạy được so sánh một cái gì đó của loại String để một cái gì đó loại Type? Tôi biết nó xử lý việc chuyển đổi/so sánh hầu hết các loại giá trị nhưng không quen thuộc với cách nó xử lý các so sánh Kiểu khác. – AndyG

+5

Có, nó sẽ hoạt động, bạn chỉ cần sử dụng phần mở rộng đánh dấu {x: Type} trong giá trị của DataTrigger. –

4

Sử dụng bộ chuyển đổi theo đề xuất của AndyG là một lựa chọn tốt. Ngoài ra, bạn cũng có thể sử dụng một khác nhau DataTemplate cho từng loại mục tiêu. WPF sẽ tự động chọn số DataTemplate khớp với loại đối tượng

+0

Nhưng nó cũng sẽ ảnh hưởng đến mọi subelement của datatype – Staeff

42

Điều này dựa trên câu trả lời của @ AndyG nhưng an toàn hơn một chút vì nó được nhập mạnh mẽ.

Thực hiện một IValueConverter tên DataTypeConverter, mà chấp nhận một đối tượng và trả về Type của nó (như là một System.Type):

public class DataTypeConverter:IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, 
     CultureInfo culture) 
    { 
     return value.GetType(); 
    } 

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

Thay đổi DataTrigger bạn để sử dụng chuyển đổi, và thiết lập giá trị Type:

<DataTrigger Binding="{Binding SelectedItem, 
     Converter={StaticResource DataTypeConverter}}" 
     Value="{x:Type local:MyType}"> 
... 
</DataTrigger> 

Declare DataTypeConverter trong các nguồn:

<UserControl.Resources> 
    <v:DataTypeConverter x:Key="DataTypeConverter"></v:DataTypeConverter> 
</UserControl.Resources> 
+1

Điều này không làm việc cho tôi. Tôi nhận được một XamlParseException nếu tôi cố gắng sử dụng một phần mở rộng đánh dấu lên trong DataTrigger.Value, vì vậy tôi đã chỉ sử dụng phương pháp so sánh chuỗi thay thế. Xem tại đây: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/14cbdb99-fd33-4ad0-8b1b-a0139c7fbf95/ – RobJohnson

+3

Kiểm tra tốt hơn nếu giá trị là null trước khi thử dùng GetType(). giá trị trả về! = null? value.GetType(): null; – Viv

+0

'Binding =" {Binding SelectedItem} "Chuyển đổi = {StaticResource DataTypeConverter}}" 'nên là' Binding = "{Ràng buộc SelectedItem, Chuyển đổi = {StaticResource DataTypeConverter}}" ' – Firo

3

Không phải là một kích hoạt nhưng điều này làm việc cho tôi. (Trigger-cách tiếp cận không vì nó không thể tạo ra một hộp kiểm cho một chuỗi này là khá nhiều Thomas Levesque's suggestion.)

sử dụng:

xmlns:mscorlib="clr-namespace:System;assembly=mscorlib" 

Một CheckBox hoặc TextBox tùy thuộc vào loại:

<ContentPresenter Content="{TemplateBinding SelectedItem}"> 
     <ContentPresenter.Resources> 
       <DataTemplate DataType="{x:Type mscorlib:Boolean}"> 
        <CheckBox Height="25" Width="25" HorizontalAlignment="Left" IsChecked="{Binding Path=.}"/> 
       </DataTemplate> 
        <DataTemplate DataType="{x:Type mscorlib:String}"> 
        <TextBox Height="25" Width="200" HorizontalAlignment="Left" Text="{Binding Path=.}"/> 
       </DataTemplate> 
     </ContentPresenter.Resources> 
</ContentPresenter> 

Lưu ý: đối với giải pháp Greg Sansom của bạn có phải trả về kiểu như string hoặc sử dụng mscorlib như trên

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