WPF自己的UserControl与ItemsSource属性

问题描述:

我想用ItemsSource属性创建一个自己的UserControl。 我已经创建了一个UserControl“myContainer”,并且我创建了一个UserControl“myItem”。现在我想在myContainer控件中显示myItem控件。所以我在myContainer控件中声明了一个依赖项PropertySource。 但是,如果我启动一个测试项目并绑定一个集合到itemssource属性什么都没有发生。是实现itemssource属性的正确方法吗?WPF自己的UserControl与ItemsSource属性

的XAML myContainer中

<UserControl x:Class="Control.myContainer" 
     ... 
     x:Name="myUserControl"> 
<Grid> 
    <DockPanel x:Name="myDockPanel"> 

    </DockPanel> 
</Grid> 

代码隐藏myContainer中

public partial class myContainer : UserControl, INotifyPropertyChanged 
{ 
    public static readonly DependencyProperty ItemsSourceProperty = 
      DependencyProperty.Register("ItemsSource", typeof(myItem), typeof(myContainer)); 

    public myContainer() 
    { 
     InitializeComponent(); 
     DataContext = this; 
    } 

    public ObservableCollection<myItem> ItemsSource 
    { 
     get 
     { 
      return (ObservableCollection<myItem>)GetValue(ItemsSourceProperty); 
     } 
     set 
     { 
      SetValue(ItemsSourceProperty, value); 
      OnPropertyChanged("ItemsSource"); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void OnPropertyChanged(string propertyName) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 

     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

的XAML myItem

<UserControl x:Class="Control.myItem" 
     ... 
     d:DesignHeight="300" d:DesignWidth="300"> 
<Grid> 
    <Border BorderThickness="1" BorderBrush="Black" CornerRadius="2"> 
     <DockPanel> 
      <StackPanel DockPanel.Dock="Top" Background="LightGray"> 
       <DockPanel Margin="2,2,2,2"> 
        <Button x:Name="Button_Close" DockPanel.Dock="Right" Width="14" Height="14" Margin="5,0,0,0" VerticalAlignment="Center"></Button> 
        <Button x:Name="Button_Undock" DockPanel.Dock="Right" Width="14" Height="14" Margin="5,0,0,0" VerticalAlignment="Center"></Button> 
        <TextBlock DockPanel.Dock="Left" VerticalAlignment="Center" FontWeight="Bold" Text="{Binding Header,UpdateSourceTrigger=PropertyChanged}"></TextBlock> 
       </DockPanel> 
      </StackPanel> 
      <ContentPresenter DockPanel.Dock="Top" ContentSource="Content"></ContentPresenter> 
     </DockPanel> 
    </Border> 
</Grid> 

代码隐藏myItem

public partial class myItem : UserControl, INotifyPropertyChanged 
{ 
    public static DependencyProperty _Header = 
      DependencyProperty.Register("Header", typeof(String), typeof(myItem), new UIPropertyMetadata("Item")); 

    public myItem() 
    { 
     InitializeComponent(); 
     DataContext = this; 
    } 

    public String Header 
    { 
     get 
     { 
      return (String)GetValue(_Header); 
     } 
     set 
     { 
      SetValue(_Header, value); 
      OnPropertyChanged("Header"); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void OnPropertyChanged(string propertyName) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 

     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 
+1

这将是容易得多从列表框或ItemsControl的导出并设定[ItemsPanel](http://msdn.microsoft.com/en-us/library/system.windows .controls.itemscontrol.itemspanel.aspx)属性添加到DockPanel。通过重写[GetContainerForItemOverride](http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.getcontainerforitemoverride.aspx),您可以创建自己的项目类型。 – Clemens 2013-02-26 08:29:29

+0

@Clemens我认为这是问题的答案而不是评论 – 2013-02-26 09:34:13

+0

你能告诉我一个例子吗? – user2025830 2013-02-26 09:58:31

好像你有,它看起来像这样的项目类型:

public class DataItem 
{ 
    public string Header { get; set; } 
    public object Content { get; set; } 
} 

您可以显示借助于这种类型的项目的列表框,其中DataTemplate表示由ItemTemplate属性设置的项目:

<ListBox ItemsSource="{Binding DataItems}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <Border BorderThickness="3" BorderBrush="Aqua"> 
       <StackPanel Margin="10"> 
        <TextBlock Text="{Binding Header}"/> 
        <ContentPresenter Content="{Binding Content}"/> 
       </StackPanel> 
      </Border> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

你当然可以使用专门的用户控件中的DataTemplate内:

<DataTemplate> 
    <Border BorderThickness="3" BorderBrush="Aqua"> 
     <StackPanel Margin="10"> 
      <TextBlock Text="{Binding Header}"/> 
      <local:MyItemControl Content="{Binding Content}"/> 
     </StackPanel> 
    </Border> 
</DataTemplate> 

一个列表框使用的默认面板是VirtualizingStackPanel。如果你想使用一个DockPanel中相反,你可以通过设置ItemsPanel属性achive说:

<ListBox ItemsSource="{Binding DataItems}"> 
    <ListBox.ItemsPanel> 
     <ItemsPanelTemplate> 
      <DockPanel /> 
     </ItemsPanelTemplate> 
    </ListBox.ItemsPanel> 
    ... 
</ListBox> 

编辑:使用一个DataTemplate你也可以完全通过更换更换一个ListBoxItem的外观而不是其的ControlTemplate在Style在ItemsContainerStyle

<ListBox ItemsSource="{Binding DataItems}"> 
    <ListBox.ItemContainerStyle> 
     <Style TargetType="ListBoxItem"> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="ListBoxItem"> 
         <Border BorderThickness="3" BorderBrush="Aqua"> 
          <StackPanel Margin="10"> 
           <TextBlock Text="{Binding Header}"/> 
           <ContentPresenter Content="{Binding Content}"/> 
          </StackPanel> 
         </Border> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </ListBox.ItemContainerStyle> 
    ... 
</ListBox> 
+0

有没有办法在列表框项目中显示usercontrol?我这样做,但是当我单击用户控件中的一个按钮,例如只选择listboxitem – user2025830 2013-02-26 14:22:41

+0

您可以设置[ItemContainerStyle](http://msdn.microsoft.com/en-us/library/system.windows.controls。 itemscontrol.itemcontainerstyle.aspx)而不是ItemTemplate。 – Clemens 2013-02-26 14:25:49

+0

我只找到一种样式ListBoxItem的方法,但是我无法使用usercontrol中的对象:/ – user2025830 2013-02-26 15:21:26