2016-11-04 77 views
3

我有一個用戶控件內的列表框來管理具有不同屬性的不同實體。 UserControl對於所有實體都是相同的。 我使用MVVM,並將一個通用的ViewModel作爲DataContext綁定到UserControl。 我希望爲UserControl的容器xaml中的Listbox設置ItemTemplate以顯示實體屬性。 對於實體「Emlployee」,我需要顯示FullName,對於實體Certifying,我需要顯示CertifyingAuthor和CertifyingDate等等。設置用戶控件內的列表框的項目模板

我需要的是類似於

<StackPanel Grid.Row="0" Orientation="Vertical"> 
     <uc:SearchableFromListTextBox ItemTemplateForTheInsideListBox="{StaticResource Something}" ></uc:SearchableFromListTextBox> 

我要補充一個DependencyProperty ItemTemplateForTheInsideListBoxProperty到該用戶控件的東西嗎?而我怎麼能通過它作爲ListBox的itemtemplate?

希望這個問題很好地解釋考慮我的意大利母語。 謝謝

編輯:我放棄了。這是一個控制鍵盤數據輸入和類似於自動完成的東西。 因爲我不得不同意與MVVM的妥協:(我會選擇一些骯髒的方式來解決。 感謝所有

+0

你真的應該使用類型的ViewModels而不是通用。它使生活更容易。 http://stackoverflow.com/questions/19864891/wpf-mvvm-why-use-contentcontrol-datatemplate-views-rather-than-straight-xaml-w – Mat

+0

你也可以使用模板選擇器。但我仍然建議你製作不同的ViewModels並使用'DataTemplate.TargetType'https://msdn.microsoft.com/en-us/library/system.windows.controls.datatemplateselector(v = vs.110).aspx – Mat

+0

看來使用DataTemplates會導致整個用戶控件的設計。我希望剩下的控制權保持不變。唯一的區別是在列表框控件的項目模板上 –

回答

0

一個DataTemplateSelector可以做什麼,我想你想要的。你可以定義從用戶控件的不同模板XAML,然後有選擇選擇其中

承擔這些模型類:

public class Employee 
{ 
    public Employee(string fullName) 
    { 
     FullName = fullName; 
    } 

    public string FullName { get; } 
} 

public class Certifying 
{ 
    public Certifying(string certifyingAuthor, DateTime certifyingDate) 
    { 
     CertifyingAuthor = certifyingAuthor; 
     CertifyingDate = certifyingDate; 
    } 

    public string CertifyingAuthor { get; } 

    public DateTime CertifyingDate { get; } 
} 

用戶控件的XAML有ListBox,進而在使用模板選擇器(我們會得到時刻) - 並且還爲其定義了不同的模板兩種不同的模型類型:

<UserControl 
    x:Class="WPF.UserControl1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WPF" 
    > 
    <Grid> 
     <ListBox x:Name="listBox"> 
      <ListBox.ItemTemplateSelector> 
       <local:MyTemplateSelector> 
        <local:MyTemplateSelector.EmployeeTemplate> 
         <DataTemplate DataType="local:Employee"> 
          <TextBlock 
           Foreground="Red" 
           Text="{Binding FullName}" 
          /> 
         </DataTemplate> 
        </local:MyTemplateSelector.EmployeeTemplate> 
        <local:MyTemplateSelector.CertifyingTemplate> 
         <DataTemplate DataType="local:Certifying"> 
          <Grid> 
           <Grid.ColumnDefinitions> 
            <ColumnDefinition Width="120" /> 
            <ColumnDefinition Width="Auto" /> 
           </Grid.ColumnDefinitions> 
           <TextBlock 
            Foreground="Blue" 
            Text="{Binding CertifyingAuthor}" 
           /> 
           <TextBlock 
            Grid.Column="1" 
            Foreground="Green" 
            Text="{Binding CertifyingDate}" 
           /> 
          </Grid> 
         </DataTemplate> 
        </local:MyTemplateSelector.CertifyingTemplate> 
       </local:MyTemplateSelector> 
      </ListBox.ItemTemplateSelector> 
     </ListBox> 
    </Grid> 
</UserControl> 

用戶控件的代碼隱藏,在這裏我只是分配模型對象的列表,列表框(爲簡單起見):

public partial class UserControl1 
{ 
    public UserControl1() 
    { 
     InitializeComponent(); 
     listBox.ItemsSource = new List<object> 
      { 
       new Employee("Donald Duck"), 
       new Certifying("Mickey Mouse", DateTime.Now), 
       new Employee("Napoleon Bonaparte"), 
       new Certifying("Homer Simpson", DateTime.Now - TimeSpan.FromDays(2)), 
      }; 
    } 
} 

最後,模板選擇。它的兩個屬性是從用戶控件的XAML中設置的;的SelectTemplate邏輯決定要應用哪個之一:

public class MyTemplateSelector : DataTemplateSelector 
{ 
    /// <summary> 
    /// This property is set from XAML. 
    /// </summary> 
    public DataTemplate EmployeeTemplate { get; set; } 

    /// <summary> 
    /// This property is set from XAML. 
    /// </summary> 
    public DataTemplate CertifyingTemplate { get; set; } 

    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     if (item is Employee) 
     { 
      return EmployeeTemplate; 
     } 

     if (item is Certifying) 
     { 
      return CertifyingTemplate; 
     } 

     return base.SelectTemplate(item, container); 
    } 
} 

而且,爲了完整性,用戶控制裝置的使用情況:

<Grid> 
    <wpf:UserControl1 /> 
</Grid> 

最終結果,其中拿破崙當前選擇,和荷馬遭受鼠標-over:

enter image description here

+0

謝謝彼得爲你解答。事實是,每當新的對象類型出現時,您的解決方案都需要實現usercontrol。另一方面,我相信模板選擇器可以移動到資源字典,避免用戶控制實現。 所以我想我可以標記爲答案。 再次感謝 感謝@Mat誰給了可能相同的答案,但我想我不明白 –

+0

用「Think」替換第一個「猜測」,第二個用「Believe」替換。我檢查了wordreference.com上的含義:)(希望它現在正確) –

+0

是的,您可以將模板選擇器移動到資源字典中。我會。 :-) –