2012-10-07 57 views
1

我创建了一个UserControl(MediaList),其中包含绑定到属性“ToolsBar”的ItemControl。这个想法是允许从MediaList控件外部添加自定义按钮/控件。绑定到包含ItemControl数据的UserControl

我的问题是,我试图将一个按钮添加到具有绑定到UserControl本身的ToolsBar。我不重写我的MediaList(UserControl)的DataContext为“this”,因为我需要使用在根窗口中定义的DataModel。

也许我这样做的方式是完全错误的?

这里是使用自定义按钮将medialist中的该窗口的为例:

<localControls:MediaList x:Name="NewMediaList"> 
       <localControls:MediaList.ToolsBar> 
        <Button Content="{StaticResource ResourceKey=MoveToPlaylist}" 
          IsEnabled="{Binding ElementName=NewMediaList, Path=SelectedMedia, Converter={localConverters:ObjectToBool}}"/> 
       </localControls:MediaList.ToolsBar> 
      </localControls:MediaList> 

直到现在我试图多个种如没有成功绑定:

  • {结合的ElementName = MediaListControl,Path = SelectedMedia,Converter = {localConverters:ObjectToBool}}“
  • {Binding RelativeSource = {x:Static RelativeSource.Self},Path = SelectedMedia,Converter = {localConverters:Debug}}
  • {结合SelectedMedia,的RelativeSource = {的RelativeSource FindAncestor,AncestorType = {X:类型用户控件}}}
  • {结合SelectedMedia,的RelativeSource = {的RelativeSource FindAncestor,AncestorType = {X:类型localControls:medialist中}}}

注意我把它们从我的记忆中写回来,我也尝试过(并且没有)将MediaControl.xaml中的ItemControl和StackPanel(它包含ItemControm)的DataContext设置为MediaList对象本身。

MediaList.xaml:

<UserControl x:Class="MediaPlaylist.Controls.MediaList" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:localConverters="clr-namespace:Suisse.MediaPlaylist.Converters" 
     mc:Ignorable="d" 
     d:DesignHeight="300" d:DesignWidth="300" 
     x:Name="MediaListControl"> 
<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="*" /> 
     <RowDefinition Height="Auto"/> 
    </Grid.RowDefinitions> 

    <DataGrid Grid.Row="0" 
       AutoGenerateColumns="False" 
       ItemsSource="{Binding ElementName=MediaListControl, Path=Playlist.Medias}" 
       SelectedItem="{Binding ElementName=MediaListControl, Path=SelectedMedia, Mode=TwoWay}"> 
     <DataGrid.Columns> 
      <DataGridTextColumn Header="Title" 
           Binding="{Binding Title}" 
           IsReadOnly="True"/> 
      <DataGridTextColumn Header="File" 
           Binding="{Binding FilePath}" 
           IsReadOnly="True"/> 
     </DataGrid.Columns> 
    </DataGrid> 

    <StackPanel Orientation="Horizontal" 
       HorizontalAlignment="Right" 
       Grid.Row="1"> 
     <ItemsControl ItemsSource="{Binding ElementName=MediaListControl, Path=ToolsBar}"> 
      <ItemsControl.ItemsPanel> 
       <ItemsPanelTemplate> 
        <StackPanel Orientation="Horizontal" /> 
       </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 
     </ItemsControl> 
     <Separator Visibility="{Binding ElementName=MediaListControl, Path=ToolsBar.Count, Converter={localConverters:ObjectToVisibility}}" /> 
     <Button 
      HorizontalAlignment="Right" 
      Content="Delete" 
      Click="OnDelete_Click" 
      IsEnabled="{Binding ElementName=MediaListControl, Path=SelectedMedia, Converter={localConverters:ObjectToBool}}"/> 
    </StackPanel> 
</Grid> 

感谢

+0

您是否尝试过使用全名称空间来设置祖先类型:{x:Type localControls:MediaList}? – zahir

+0

Oups我在我的问题中犯了一个错误,但是我在编写时使用了完整的命名空间({x:Type localControls:MediaList}) – 0xCDCDCDCD

回答

0

首先,您要指定绑定数据的ItemsControl的ItemsSource属性,这是完全错误的。 取而代之的是,你可以在你的MedialList.xaml.cs声明ItemsControl的依赖属性

 public partial class MediaList : UserControl 
    { 
     public MediaList() 
     { 
      InitializeComponent(); 

     } 

     public static DependencyProperty ToolsBarProperty = DependencyProperty. 
    Register("ToolsBar", typeof(ItemsControl), typeof(MediaList)); 

     public ItemsControl ToolsBar 
     { 
      get { return (ItemsControl)GetValue(ToolsBarProperty); } 
      set { SetValue(ToolsBarProperty, value); } 
     } 
    } 

然后,您可以更新medialist中的XAML为

<StackPanel Orientation="Horizontal" 
      HorizontalAlignment="Right" 
      Grid.Row="1"> 
     <ContentControl Content="{Binding ElementName=MediaListControl, Path=ToolsBar}"> 

     </ContentControl> 

然后你就可以从外部指派任何集合模板工具栏属性as

<localControls:MediaList> 
      <localControls:MediaList.ToolsBar> 
       <ItemsControl > 
        <ItemsControl.Items> 
         <Button Content="{StaticResource ResourceKey=MoveToPlaylist}" 
         IsEnabled="{Binding ElementName=NewMediaList, Path=SelectedMedia, Converter={localConverters:ObjectToBool}}"/> 
         <Label>Hello </Label> 
         <Label> How are you?</Label> 
        </ItemsControl.Items> 
        <ItemsControl.ItemsPanel> 
         <ItemsPanelTemplate> 
          <StackPanel Orientation="Horizontal" /> 
         </ItemsPanelTemplate> 
        </ItemsControl.ItemsPanel> 
       </ItemsControl> 
      </localControls:MediaList.ToolsBar> 
     </localControls:MediaList> 

希望这能解决您的问题。

注:我刚刚搬出了MediaList用户控件中定义的ItemsControl,并将其替换为ContentControl。这允许从外部设置ContentControl的Content属性的任何模板。

+0

为什么使用ItemControl.ItemsSource会是一个坏主意?从文档中,该属性适用于原始数据(例如字符串)和UIElement。 这个想法是给MediaList的控件列表,并让它应用一个模板(并保持简单的父母将使用MediaList),无论如何,我尝试了你的示例,但绑定仍然无法正常工作。 我收到通知,如果创建一个标签(在使用MediaList的同一文件中)和MediaList本身之外的NewMediaList绑定,它将工作,如果我将标签移动到ToolsBar中,则NewMediaList未找到。 – 0xCDCDCDCD

+0

运行应用程序时可以检查输出,看看是否有任何绑定异常没有被抛出?我怀疑可能存在绑定错误。还有你宣布SelectedMedia作为MediaList.xaml.cs内的依赖项属性? – RockWorld

+0

有一个绑定异常(错误:4:找不到与引用绑定的源'ElementName = NewMediaList'。BindingExpression:Path = SelectedMedia; DataItem = null;目标元素为'Button'(Name ='');目标属性为'IsEnabled'(类型'布尔'))和SelectedMedia是一个有用的属性。 (MediaList中的一个按钮绑定到这个属性并且工作正常) 就像我说的绑定到ElementName = NewMediaList的虚拟标签只在外部localControls时才起作用:MediaList.ToolsBar标签... wpf决定的对象绑定似乎与MediaList内部/外部不同 – 0xCDCDCDCD