2013-10-24 56 views
0

假設在一個XAML窗口,我有<UserControl x:Name="Test">... 我有一個自定義MyListBoxItem只有一個的DependencyProperty UserControlProperty添加的typeof UserControl的TypeConverter到用戶控件

我想使用語法<c:MyListBoxItem UserControl="Test">Information</c:MyListBoxItem>,我不知道如何從字符串「Test」或者「local:Test」向xaml頁面上的usercontrol Test編寫一個typeconverter。

在回答 '尼特' 的評論:

<Window.Resources> 
    <UserControl x:Key="Test" x:Name="Test" 
       x:Shared="False"> 
     <Button Height="50" 
       Width="50" /> 
    </UserControl> 
</Window.Resources> 

<c:MyListBoxItem UserControl="{StaticResource Test}">Information</c:MyListBoxItem>作品。 但是我想要的用戶控件在常規XAML的定義,發現這樣做的另外兩種方式:

<c:MyListBoxItem UserControl="{x:Reference Test}"> 

然而x:Reference給出了complie時錯誤:未實現的方法/操作。它仍然運行哪個btw很奇怪imo。並且:

<c:MyListBoxItem UserControl="{Binding ElementName=Test}" 

這是很好的解決方案。

至於什麼,你可以通過這個實現:

private void Menu_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    foreach (var item in e.RemovedItems) 
    { 
    // collapse usercontrol 
    UserControl uc = (item as MyListBoxItem).UserControl; 
    if (uc != null) uc.Visibility = Visibility.Collapsed; 
      } 
    foreach (var item in e.AddedItems) 
    { 
    // uncollapse usercontrol 
    UserControl uc = (item as MyListBoxItem).UserControl; 
    if (uc != null) uc.Visibility = Visibility.Visible; 
    } 
} 

這是一個很好的方式來支持這種菜單結構和XAML的定義也澄清:

<c:MyListBoxItem UserControl="{Binding ElementName=Information}" IsSelected="True">Information</c:MyListBoxItem> 
<c:MyListBoxItem UserControl="{Binding ElementName=Edit}" IsSelected="False">Edit</c:MyListBoxItem> 

<Grid> 
    <UserControl x:Name="Information" Visibility="Visible"><Button Content="Placeholder for usercontrol Information" /></UserControl> 
    <UserControl x:Name="Edit" Visibility="Collapsed"> <Button Content="Placeholder for usercontrol Edit" /></UserControl> 

回答

1

我不是確定你想要做到這一點,但你將不得不把這個UserControl的資源

<Window.Resources> 
<UserControl x:Key="Test" x:Shared="false"> 
</Window.Resources> 

然後你可以設置你的DP作爲

<c:MyListBoxItem UserControl="{StaticResource Test}">Information</c:MyListBoxItem> 
+0

This Works! usercontrol屬性被設置,這是一件好事。但是我注意到SelectionChanged事件中UserControl的Content和Name屬性是空的? – Gerard

+0

你可以分享如何設置資源中的用戶控件的名稱和內容? – Nitin

+0

對不起,它的工作原理,我忘了給usercontrol的x:Name屬性。查看我的編輯以獲得更好的解決方案。 – Gerard

1

如果你想用一個實際的TypeConverter,你應該能夠做這樣的事情:

public class UserControlConverter : TypeConverter 
{ 
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) 
    { 
     if (sourceType == typeof(string)) return true; 
     return base.CanConvertFrom(context, sourceType); 
    } 

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) 
    { 
     if (value is string) 
     { 
      Type userControlType = Type.GetType(value.ToString(), true, true); 
      return Activator.CreateInstance(userControlType); 
     } 
     return base.ConvertFrom(context, culture, value); 
    } 

    public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) 
    { 
     if (destinationType == typeof(UserControl)) 
     { 
      return destinationType.FullName; 
     } 
     return base.ConvertTo(context, culture, value, destinationType); 
    } 
} 

我還沒有機會測試這個,所以請讓我知道你是否有任何問題。此外,請注意,您需要使用該類型的全名,例如:ApplicationName.ProjectOrFolderNameIfApplicable.ControlName。另請注意,這隻會調用UserControl的默認(空)構造函數。

+0

是否可以使用'Activator.CreateInstance(userControlType)'來查找已經在xaml中聲明的現有用戶控件? – Gerard

+0

任何事情都是可能的,但我不會在'TypeConverter'中推薦這樣做。如果你想這樣做,那麼我會推薦使用nit爲你提供的方法。 – Sheridan

+0

@Gerard,如果有幫助,你可以使用Activator類來調用一個特定的構造函數,在這個構造函數中你可以執行一些設置功能。 – Sheridan