1
votes

I created a UserControl (MediaList) which contains an ItemControl which is binded to a property "ToolsBar". The idea is to allow to add custom button/controls from outside the MediaList control.

My problem is that i'm trying to add a button into the ToolsBar which have a binding to the UserControl itself. I don't override the DataContext of my MediaList (UserControl) to be "this" since i'm needing to use my DataModel which is defined in the root window.

Maybe the way I'm doing this is complety wrong?

Here is an exemple of the window which use a custom button to the 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>

Until now I tried multiple kind of binding without success such as :

  • {Binding ElementName=MediaListControl, Path=SelectedMedia, Converter={localConverters:ObjectToBool}}"
  • {Binding RelativeSource={x:Static RelativeSource.Self}, Path=SelectedMedia, Converter={localConverters:Debug}}
  • {Binding SelectedMedia, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}
  • {Binding SelectedMedia, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type localControls:MediaList}}}

Take note I write them back from my memory and that I also tried with (and without) setting the DataContext of the ItemControl and StackPanel (which contains the ItemControm) from MediaList.xaml to be the MediaList object itself.

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>

Thanks

1
Have you tried setting ancestor type with full namespace like: {x:Type localControls:MediaList} ?zahir
Oups I did a mistake in my question but yes I used the full namespace as you write ({x:Type localControls:MediaList})0xCDCDCDCD

1 Answers

0
votes

First, you are trying to assign binding data to ItemsSource property of ItemsControl, which is completely wrong. Instead of that you can declare ItemsControl dependency property in your MedialList.xaml.cs

        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); }
        }
    }

You can then update MediaList xaml as

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

        </ContentControl>

Then you can assign any collection template from outside to ToolBar property 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>

Hope this will solve your problem.

Note: I have just moved out ItemsControl defined inside MediaList user control and replaced it with ContentControl. This allows to set any template from outside to Content property of ContentControl.