为什么在数据模板中使用 xaml UserControl 时无法绑定到依赖属性?
Why am I unable to bind to dependency properties in my xaml UserControl when using it in a data template?
我正在尝试通过一些副项目来提高我的 WPF 技能 - 当前的项目是创建 Windows 文件资源管理器的小型克隆。
我目前正在做 'This PC' 部分 - 制作一个用户控件来模仿 Explorer 显示磁盘的方式,即 Explorer 有这个:
我的克隆有这个:
在此用户控件 (Drive.xaml
& Drive.xaml.cs
) 中,我创建了几个我希望能够绑定的依赖属性以便传入数据,即卷标、磁盘名称、使用百分比等...:[=22=]
Drive.xaml.cs
- 为简洁起见缩短
public partial class Drive : UserControl
{
/// <summary>
/// Using a DependencyProperty as the backing store for DriveName. This enables animation, styling, binding, etc...
/// </summary>
public static readonly DependencyProperty DriveNameProperty =
DependencyProperty.Register("DriveName", typeof(string), typeof(Drive), new PropertyMetadata(string.Empty));
/// <summary>
/// Initializes a new instance of the <see cref="Drive" /> class
/// </summary>
public Drive()
{
this.InitializeComponent();
}
/// <summary>
/// Gets or sets the <see cref="DriveNameProperty" /> dependency property
/// </summary>
public string DriveName
{
get => (string)this.GetValue(DriveNameProperty);
set => this.SetValue(DriveNameProperty, value);
}
}
Drive.xaml
- 也缩短了
<UserControl x:Class="Explorer.View.Components.Hardware.Drive"
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"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
d:DesignHeight="60"
d:DesignWidth="260">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="15"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="200" />
</Grid.ColumnDefinitions>
<Image Width="50" VerticalAlignment="Center" Grid.Row="0" Grid.Column="0" Grid.RowSpan="3" Source="{StaticResource DriveIcon}" />
<TextBlock Grid.Row="0" Grid.Column="1">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} ({1})">
<Binding Path="VolumeLabel"/>
<Binding Path="DriveName"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<ProgressBar Grid.Row="1" Grid.Column="1" Value="{Binding PercentageUsedBar}" Foreground="CornflowerBlue" />
<TextBlock Grid.Row="2" Grid.Column="1" Text="[x TB free of y TB]"/>
</Grid>
</UserControl>
当我尝试将此控件用作数据模板的一部分时,出现了我遇到的问题。我可以在不绑定的情况下使用这些依赖属性:
<!-- this works and renders correctly -->
<hardware:Drive PercentageUsedBar="25" DriveName="C:\" VolumeLabel="Reece"/>
但显然这没有多大用处。所以我有一个 ViewModel,它提供来自文件系统的相关真实数据,我试图绑定到它的详细信息,以便呈现所有连接到我的系统的磁盘:
<!-- this does not work for some reason -->
<ItemsControl ItemsSource="{Binding FixedDrives}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Style="{StaticResource TabButtonStyle}">
<hardware:Drive Margin="5"
DriveName="{Binding Drive.Name}"
VolumeLabel="{Binding Drive.VolumeLabel}"
PercentageUsedBar="{Binding PercentageSpaceUsed}"/>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
但这只会给我每个磁盘的绑定失败:
任何帮助将不胜感激,我已经开始抓狂了!
您正在“覆盖”继承的 DataContext
。
从 UserControl
中删除它,即不要明确设置其 DataContext
:
DataContext="{Binding RelativeSource={RelativeSource Self}}"
...并指定每个绑定的来源:
<TextBlock Grid.Row="0" Grid.Column="1">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} ({1})">
<Binding Path="VolumeLabel" RelativeSource="{RelativeSource AncestorType=UserControl}"/>
<Binding Path="DriveName" RelativeSource="{RelativeSource AncestorType=UserControl}"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
我正在尝试通过一些副项目来提高我的 WPF 技能 - 当前的项目是创建 Windows 文件资源管理器的小型克隆。
我目前正在做 'This PC' 部分 - 制作一个用户控件来模仿 Explorer 显示磁盘的方式,即 Explorer 有这个:
我的克隆有这个:
在此用户控件 (Drive.xaml
& Drive.xaml.cs
) 中,我创建了几个我希望能够绑定的依赖属性以便传入数据,即卷标、磁盘名称、使用百分比等...:[=22=]
Drive.xaml.cs
- 为简洁起见缩短
public partial class Drive : UserControl
{
/// <summary>
/// Using a DependencyProperty as the backing store for DriveName. This enables animation, styling, binding, etc...
/// </summary>
public static readonly DependencyProperty DriveNameProperty =
DependencyProperty.Register("DriveName", typeof(string), typeof(Drive), new PropertyMetadata(string.Empty));
/// <summary>
/// Initializes a new instance of the <see cref="Drive" /> class
/// </summary>
public Drive()
{
this.InitializeComponent();
}
/// <summary>
/// Gets or sets the <see cref="DriveNameProperty" /> dependency property
/// </summary>
public string DriveName
{
get => (string)this.GetValue(DriveNameProperty);
set => this.SetValue(DriveNameProperty, value);
}
}
Drive.xaml
- 也缩短了
<UserControl x:Class="Explorer.View.Components.Hardware.Drive"
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"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
d:DesignHeight="60"
d:DesignWidth="260">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="15"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="200" />
</Grid.ColumnDefinitions>
<Image Width="50" VerticalAlignment="Center" Grid.Row="0" Grid.Column="0" Grid.RowSpan="3" Source="{StaticResource DriveIcon}" />
<TextBlock Grid.Row="0" Grid.Column="1">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} ({1})">
<Binding Path="VolumeLabel"/>
<Binding Path="DriveName"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<ProgressBar Grid.Row="1" Grid.Column="1" Value="{Binding PercentageUsedBar}" Foreground="CornflowerBlue" />
<TextBlock Grid.Row="2" Grid.Column="1" Text="[x TB free of y TB]"/>
</Grid>
</UserControl>
当我尝试将此控件用作数据模板的一部分时,出现了我遇到的问题。我可以在不绑定的情况下使用这些依赖属性:
<!-- this works and renders correctly -->
<hardware:Drive PercentageUsedBar="25" DriveName="C:\" VolumeLabel="Reece"/>
但显然这没有多大用处。所以我有一个 ViewModel,它提供来自文件系统的相关真实数据,我试图绑定到它的详细信息,以便呈现所有连接到我的系统的磁盘:
<!-- this does not work for some reason -->
<ItemsControl ItemsSource="{Binding FixedDrives}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Style="{StaticResource TabButtonStyle}">
<hardware:Drive Margin="5"
DriveName="{Binding Drive.Name}"
VolumeLabel="{Binding Drive.VolumeLabel}"
PercentageUsedBar="{Binding PercentageSpaceUsed}"/>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
但这只会给我每个磁盘的绑定失败:
任何帮助将不胜感激,我已经开始抓狂了!
您正在“覆盖”继承的 DataContext
。
从 UserControl
中删除它,即不要明确设置其 DataContext
:
DataContext="{Binding RelativeSource={RelativeSource Self}}"
...并指定每个绑定的来源:
<TextBlock Grid.Row="0" Grid.Column="1">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} ({1})">
<Binding Path="VolumeLabel" RelativeSource="{RelativeSource AncestorType=UserControl}"/>
<Binding Path="DriveName" RelativeSource="{RelativeSource AncestorType=UserControl}"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>