附加 属性 绑定在我的用户控件中失败
Attached property binding failed in my user control
我有一个UsersControl.xaml
<UserControl x:Name="userControl" x:Class="Lloyd.Shared.Controls.UsersControl"
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:Interactivity="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:Behaviors="clr-namespace:Lloyd.Shared.Controls.Behaviors"
xmlns:local="clr-namespace:Lloyd.Shared.Controls"
mc:Ignorable="d" DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}}"
d:DesignHeight="300" d:DesignWidth="300">
<Interactivity:Interaction.Behaviors>
<Behaviors:ImportUsersOnLoadedBehavior />
</Interactivity:Interaction.Behaviors>
<DockPanel LastChildFill="True">
<Label Content="账号" DockPanel.Dock="Top" FontSize="18.667" />
<StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom" HorizontalAlignment="Right">
<Button x:Name="AddAccountButton" Height="26" Width="80" Content="添加" Margin="5" Command="{Binding AddUserCommand}" />
<Button x:Name="ImportAccountsButton" Height="26" Width="80" Content="导入" Margin="5" Command="{Binding ImportUsersCommand}"/>
<Button x:Name="DeleteAccountButton" Height="26" Width="80" Content="删除" Margin="5" Command="{Binding RemoveUsersCommand}"/>
</StackPanel>
<ListView x:Name="accountListbox" Margin="5" BorderThickness="1" BorderBrush="{DynamicResource AccentColorBrush}" ItemsSource="{Binding UsersCollection}"/>
</DockPanel>
代码隐藏
public partial class UsersControl : UserControl
{
public static ObservableCollection<User> GetUsersCollection(DependencyObject obj)
{
return (ObservableCollection<User>)obj.GetValue(UsersCollectionProperty);
}
public static void SetUsersCollection(DependencyObject obj, ObservableCollection<User> value)
{
obj.SetValue(UsersCollectionProperty, value);
}
// Using a DependencyProperty as the backing store for UsersCollection. This enables animation, styling, binding, etc...
public static readonly DependencyProperty UsersCollectionProperty =
DependencyProperty.RegisterAttached("UsersCollection", typeof(ObservableCollection<User>), typeof(UsersControl), new FrameworkPropertyMetadata(null,FrameworkPropertyMetadataOptions.AffectsRender));
}
我在 MainWindow.xaml 中使用了这个 UsersControl,并将 UsersCollection 绑定到主 windows 的 DataContext。
<Controls:MetroWindow x:Class="ZggwwDocuments.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:c="clr-namespace:Lloyd.Shared.Controls;assembly=Lloyd.Shared.Controls"
xmlns:vm="clr-namespace:ZggwwDocuments.ViewModels"
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:ZggwwDocuments"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="697.514">
<Controls:MetroWindow.DataContext>
<vm:MainWindowViewModel/>
</Controls:MetroWindow.DataContext>
<Grid Margin="5">
<c:UsersControl UsersCollection="{Binding Users}" />
</Grid>
我在 MainWindow 上设置了断点,它的 DataContext 和 Users 属性 不为空。但是 MainWindow.DataContext.Users 和 UsersControl.UsersCollection 之间的绑定失败了。以下是输出window
System.Windows.Data Error: 40 : BindingExpression path error: 'Users' property not found on 'object' ''UsersControl' (Name='userControl')'. BindingExpression:Path=Users; DataItem='UsersControl' (Name='userControl'); target element is 'UsersControl' (Name='userControl'); target property is 'UsersCollection' (type 'ObservableCollection`1')
UsersControl.xaml.cs 中的 GetUsersCollection(DependencyObject obj) 总是 return null
试着像下面这样给你的附件 属性 打电话:
<c:UsersControl UsersControl.UsersCollection="{Binding Users}" />
尝试
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type c:UsersControl}}, Path=UsersCollection}"
或者,你可以机灵点;
<DockPanel LastChildFill="True">
<Label Content="账号" DockPanel.Dock="Top" FontSize="18.667" />
<StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom" HorizontalAlignment="Right">
<Button x:Name="AddAccountButton" Height="26" Width="80" Content="添加" Margin="5" Command="{Binding AddUserCommand}" />
<Button x:Name="ImportAccountsButton" Height="26" Width="80" Content="导入" Margin="5" Command="{Binding ImportUsersCommand}"/>
<Button x:Name="DeleteAccountButton" Height="26" Width="80" Content="删除" Margin="5" Command="{Binding RemoveUsersCommand}"/>
</StackPanel>
<ListView x:Name="accountListbox" Margin="5" BorderThickness="1" BorderBrush="{DynamicResource AccentColorBrush}" ItemsSource="{Binding UsersCollection}"/>
</DockPanel>
...然后把它塞进去;
<UserControl.Template>
<ControlTemplate TargetType="{x:Type UserControl}">
(paste it here)
</ControlTemplate>
</UserControl.Template>
然后将绑定更改为;
{Binding RelativeSource={RelativeSource TemplatedParent}, Path=UsersCollection}
我个人推荐这种方法而不是第一种方法,因为绑定更快,更不容易... 'issues'...而且这也意味着您要覆盖用户的模板控制成为您真正想要的样子,而不是仅仅在其现有模板中倾倒一些 XAML。
我有一个UsersControl.xaml
<UserControl x:Name="userControl" x:Class="Lloyd.Shared.Controls.UsersControl"
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:Interactivity="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:Behaviors="clr-namespace:Lloyd.Shared.Controls.Behaviors"
xmlns:local="clr-namespace:Lloyd.Shared.Controls"
mc:Ignorable="d" DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}}"
d:DesignHeight="300" d:DesignWidth="300">
<Interactivity:Interaction.Behaviors>
<Behaviors:ImportUsersOnLoadedBehavior />
</Interactivity:Interaction.Behaviors>
<DockPanel LastChildFill="True">
<Label Content="账号" DockPanel.Dock="Top" FontSize="18.667" />
<StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom" HorizontalAlignment="Right">
<Button x:Name="AddAccountButton" Height="26" Width="80" Content="添加" Margin="5" Command="{Binding AddUserCommand}" />
<Button x:Name="ImportAccountsButton" Height="26" Width="80" Content="导入" Margin="5" Command="{Binding ImportUsersCommand}"/>
<Button x:Name="DeleteAccountButton" Height="26" Width="80" Content="删除" Margin="5" Command="{Binding RemoveUsersCommand}"/>
</StackPanel>
<ListView x:Name="accountListbox" Margin="5" BorderThickness="1" BorderBrush="{DynamicResource AccentColorBrush}" ItemsSource="{Binding UsersCollection}"/>
</DockPanel>
代码隐藏
public partial class UsersControl : UserControl
{
public static ObservableCollection<User> GetUsersCollection(DependencyObject obj)
{
return (ObservableCollection<User>)obj.GetValue(UsersCollectionProperty);
}
public static void SetUsersCollection(DependencyObject obj, ObservableCollection<User> value)
{
obj.SetValue(UsersCollectionProperty, value);
}
// Using a DependencyProperty as the backing store for UsersCollection. This enables animation, styling, binding, etc...
public static readonly DependencyProperty UsersCollectionProperty =
DependencyProperty.RegisterAttached("UsersCollection", typeof(ObservableCollection<User>), typeof(UsersControl), new FrameworkPropertyMetadata(null,FrameworkPropertyMetadataOptions.AffectsRender));
}
我在 MainWindow.xaml 中使用了这个 UsersControl,并将 UsersCollection 绑定到主 windows 的 DataContext。
<Controls:MetroWindow x:Class="ZggwwDocuments.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:c="clr-namespace:Lloyd.Shared.Controls;assembly=Lloyd.Shared.Controls"
xmlns:vm="clr-namespace:ZggwwDocuments.ViewModels"
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:ZggwwDocuments"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="697.514">
<Controls:MetroWindow.DataContext>
<vm:MainWindowViewModel/>
</Controls:MetroWindow.DataContext>
<Grid Margin="5">
<c:UsersControl UsersCollection="{Binding Users}" />
</Grid>
我在 MainWindow 上设置了断点,它的 DataContext 和 Users 属性 不为空。但是 MainWindow.DataContext.Users 和 UsersControl.UsersCollection 之间的绑定失败了。以下是输出window
System.Windows.Data Error: 40 : BindingExpression path error: 'Users' property not found on 'object' ''UsersControl' (Name='userControl')'. BindingExpression:Path=Users; DataItem='UsersControl' (Name='userControl'); target element is 'UsersControl' (Name='userControl'); target property is 'UsersCollection' (type 'ObservableCollection`1')
UsersControl.xaml.cs 中的 GetUsersCollection(DependencyObject obj) 总是 return null
试着像下面这样给你的附件 属性 打电话:
<c:UsersControl UsersControl.UsersCollection="{Binding Users}" />
尝试
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type c:UsersControl}}, Path=UsersCollection}"
或者,你可以机灵点;
<DockPanel LastChildFill="True">
<Label Content="账号" DockPanel.Dock="Top" FontSize="18.667" />
<StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom" HorizontalAlignment="Right">
<Button x:Name="AddAccountButton" Height="26" Width="80" Content="添加" Margin="5" Command="{Binding AddUserCommand}" />
<Button x:Name="ImportAccountsButton" Height="26" Width="80" Content="导入" Margin="5" Command="{Binding ImportUsersCommand}"/>
<Button x:Name="DeleteAccountButton" Height="26" Width="80" Content="删除" Margin="5" Command="{Binding RemoveUsersCommand}"/>
</StackPanel>
<ListView x:Name="accountListbox" Margin="5" BorderThickness="1" BorderBrush="{DynamicResource AccentColorBrush}" ItemsSource="{Binding UsersCollection}"/>
</DockPanel>
...然后把它塞进去;
<UserControl.Template>
<ControlTemplate TargetType="{x:Type UserControl}">
(paste it here)
</ControlTemplate>
</UserControl.Template>
然后将绑定更改为;
{Binding RelativeSource={RelativeSource TemplatedParent}, Path=UsersCollection}
我个人推荐这种方法而不是第一种方法,因为绑定更快,更不容易... 'issues'...而且这也意味着您要覆盖用户的模板控制成为您真正想要的样子,而不是仅仅在其现有模板中倾倒一些 XAML。