无法将UserControl绑定到ItemsControl [重复]

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法将UserControl绑定到ItemsControl [重复]相关的知识,希望对你有一定的参考价值。

这个问题在这里已有答案:

我正在尝试用一些UserControls填充ItemsControl,但我无法找到哪个祖先应该匹配数据模板中的项目。

我已经尝试用x:Name属性绑定,结果是一样的。我也尝试使用和不使用RelativeSource进行绑定,但我也没有任何成功。

用户控制XAML

<UserControl x:Class="FireAntTempConfigurer.UserControls.CommandButton_UC"
             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:local="clr-namespace:FireAntTempConfigurer.UserControls"
             xmlns:materialDesign="clr-namespace:MaterialDesignThemes.Wpf;assembly=MaterialDesignThemes.Wpf"
             mc:Ignorable="d" 
             TextElement.Foreground="{DynamicResource MaterialDesignPaper}"
             d:DesignHeight="50 " d:DesignWidth="50"
             >
    <Grid>
        <Button Height="50" Padding="0,0,0,0" ToolTip="{Binding Path=Placeholder, RelativeSource={RelativeSource AncestorType=UserControl}}">
            <Button.Content>
                <materialDesign:PackIcon Kind="{Binding Path=Icon, RelativeSource={RelativeSource AncestorType=UserControl}}" Height="50" Width="50" />
            </Button.Content>
        </Button>
    </Grid>
</UserControl>

用户控制代码背后

    /// <summary>
    /// Interaction logic for CommandButton_UC.xaml
    /// </summary>
    public partial class CommandButton_UC : UserControl
    {

        public CommandButton_UC()
        {
            this.DataContext = this;
            InitializeComponent();
        }

        public string Icon
        {
            get { return (string)GetValue(IconProperty); }
            set { SetValue(IconProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Icon.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IconProperty =
            DependencyProperty.Register("Icon", typeof(string), typeof(CommandButton_UC), new PropertyMetadata("EmoticonDead"));

        public string Placeholder
        {
            get { return (string)GetValue(PlaceholderProperty); }
            set { SetValue(PlaceholderProperty, value); }
        }
        // Using a DependencyProperty as the backing store for Placeholder.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PlaceholderProperty =
            DependencyProperty.Register("Placeholder", typeof(string), typeof(CommandButton_UC), new PropertyMetadata("fail to load"));

    }

主窗口XAML

<Window x:Class="FireAntTempConfigurer.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:FireAntTempConfigurer"
        xmlns:materialDesign="clr-namespace:MaterialDesignThemes.Wpf;assembly=MaterialDesignThemes.Wpf"
        xmlns:uc="clr-namespace:FireAntTempConfigurer.UserControls"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800"
        TextElement.Foreground="{DynamicResource SecondaryAccentBrush}"
        Background="{DynamicResource MaterialDesignPaper}"
        TextElement.FontWeight="Medium"
        TextElement.FontSize="20"
        FontFamily="pack://application:,,,/MaterialDesignThemes.Wpf;component/Resources/Roboto/#Roboto"
        x:Name="mw">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="95*"/>
            <ColumnDefinition Width="169*"/>
            <ColumnDefinition Width="95*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition Height="150"/>
            <RowDefinition Height="50"/>
            <RowDefinition Height="50"/>
        </Grid.RowDefinitions>
        <materialDesign:Card Grid.Column="1" Grid.Row="1">
            <StackPanel Margin="0">
                <TextBlock>ToolBox:</TextBlock>
                <Separator Margin="0"></Separator>
                <ItemsControl ItemsSource="{Binding Path=MyPropertyList, RelativeSource={RelativeSource AncestorType=Window}}">
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel  Orientation="Horizontal" Height="50" HorizontalAlignment="Left" Margin="5,0,0,0" IsItemsHost="True"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ItemsControl.ItemTemplate >
                        <DataTemplate>
                            <uc:CommandButton_UC Padding="0,0,0,0" Margin="0,0,5,0" 
                                                 Icon="{Binding Path=IconProp, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
                                                 Placeholder="{Binding Path=PlaceHolderProp , RelativeSource={RelativeSource AncestorType=ItemsControl}}">
                            </uc:CommandButton_UC>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
.
.
.

主窗口代码背后

public partial class MainWindow : Window
{
    public CommandButtonViewModel MyProperty { get; set; }
    public BindingList<CommandButtonViewModel> MyPropertyList { get; set; }
    public MainWindow()
    {
        MyPropertyList = new BindingList<CommandButtonViewModel>();
        MyProperty = new CommandButtonViewModel { IconProp = "PlusCircleOutline", PlaceHolderProp = "Add" };
        BindingList<CommandButtonViewModel> tempList = new BindingList<CommandButtonViewModel>();
        tempList.Add(MyProperty);
        tempList.Add(MyProperty);
        MyPropertyList = tempList;
        DataContext = this;
        InitializeComponent();
    }

现在我在输出端收到消息:

System.Windows.Data Error: 40 : BindingExpression path error: 'IconProp' property not found on 'object' ''CommandButton_UC' (Name='')'. BindingExpression:Path=IconProp; DataItem='CommandButton_UC' (Name=''); target element is 'CommandButton_UC' (Name=''); target property is 'Icon' (type 'String')
System.Windows.Data Error: 40 : BindingExpression path error: 'IconProp' property not found on 'object' ''CommandButton_UC' (Name='')'. BindingExpression:Path=IconProp; DataItem='CommandButton_UC' (Name=''); target element is 'CommandButton_UC' (Name=''); target property is 'Icon' (type 'String')
System.Windows.Data Error: 40 : BindingExpression path error: 'PlaceHolderProp' property not found on 'object' ''ItemsControl' (Name='')'. BindingExpression:Path=PlaceHolderProp; DataItem='ItemsControl' (Name=''); target element is 'CommandButton_UC' (Name=''); target property is 'Placeholder' (type 'String')
System.Windows.Data Error: 40 : BindingExpression path error: 'PlaceHolderProp' property not found on 'object' ''ItemsControl' (Name='')'. BindingExpression:Path=PlaceHolderProp; DataItem='ItemsControl' (Name=''); target element is 'CommandButton_UC' (Name=''); target property is 'Placeholder' (type 'String')

会感激一些帮助

答案

我无法完全复制你的代码,因为我没有materialdesignlibrary,但我认为我可以重现你的情况,用普通的wpf控件替换那些引用。在我看来,你必须执行以下步骤:

  1. 检查CommandButtonViewModel是否真的是一个viewmodel所以它必须实现这样的INotifyPropertyChanged: public class CommandButtonViewModel : INotifyPropertyChanged { private string _iconprop; public string IconProp { get { return _iconprop; } set { _iconprop = value; NotifyPropertyChanged("IconProp"); } } private string _placeholderprop; public string PlaceHolderProp { get { return _placeholderprop; } set { _placeholderprop = value; NotifyPropertyChanged("PlaceHolderProp"); } } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String propertyName = "") { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } 您的DataContext只是主窗口,因此从CommandButton_UC的创建者中删除DataContext集 public partial class CommandButton_UC : UserControl { public CommandButton_UC() { InitializeComponent(); } } 在绑定中,您可以直接绑定到CommandButtonViewModel属性 所以你必须以这种方式修改CommandButton_UC: <ItemsControl ItemsSource="{Binding Path=MyPropertyList, RelativeSource {RelativeSource AncestorType=Window}}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal" Height="50" HorizontalAlignment="Left" Margin="5,0,0,0" IsItemsHost="True"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate > <DataTemplate> <uc:CommandButton_UC Padding="0,0,0,0" Margin="0,0,5,0" Icon="{Binding Path=IconProp}" Placeholder="{Binding Path=PlaceHolderProp}"> </uc:CommandButton_UC> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl>

以上是关于无法将UserControl绑定到ItemsControl [重复]的主要内容,如果未能解决你的问题,请参考以下文章

为啥在数据模板中使用 xaml UserControl 时无法绑定到依赖属性? [复制]

有点时候,需要利用UserControl占位模板,动态替换的情况,绑定后无法获取DataContext的问题

WPF - 将 UserControl 可见性绑定到属性

将 UserControl ListBox ItemSsource 绑定到父 DataContext 时出错

将 Silverlight UserControl 自定义属性绑定到其元素

wpf usercontrol,将按钮的命令参数绑定到父用户控件