绑定到包含ItemControl数据的UserControl

时间:2022-12-14 19:35:57

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.

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

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.

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

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 :

这是一个窗口的例子,它使用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 ElementName = MediaListControl,Path = SelectedMedia,Converter = {localConverters:ObjectToBool}}“

  • {Binding RelativeSource={x:Static RelativeSource.Self}, Path=SelectedMedia, Converter={localConverters:Debug}}
  • {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 UserControl}}}

  • {Binding SelectedMedia, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type localControls:MediaList}}}
  • {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.

请注意我从内存中写回来,并且我也试过(并且没有)将MediaControl的DataContext和MediaList.xaml中的StackPanel(包含ItemControm)设置为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>

Thanks

1 个解决方案

#1


0  

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

首先,您尝试将绑定数据分配给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); }
        }
    }

You can then update MediaList xaml as

然后,您可以将MediaList xaml更新为

 <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

然后,您可以将任何集合模板从外部分配给ToolBar属性

<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.

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

#1


0  

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

首先,您尝试将绑定数据分配给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); }
        }
    }

You can then update MediaList xaml as

然后,您可以将MediaList xaml更新为

 <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

然后,您可以将任何集合模板从外部分配给ToolBar属性

<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.

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

相关文章