【发布时间】:2018-03-01 13:21:54
【问题描述】:
我有一个名为ReferencedItem 的自定义用户控件。它应该采用一个名为 ItemId 的 Guid。它是这样实现的:
private static void OnItemIdChanged(DependencyObject dobj, DependencyPropertyChangedEventArgs dpArgs)
{
//Do something
}
public static readonly DependencyProperty ItemIdProperty = DependencyProperty.Register("ItemId", typeof(Guid?), typeof(ReferencedItem), new FrameworkPropertyMetadata(
// use an empty Guid as default value
Guid.Empty,
// tell the binding system that this property affects how the control gets rendered
FrameworkPropertyMetadataOptions.AffectsRender,
// run this callback when the property changes
OnItemIdChanged
));
public Guid? ItemId
{
get { return (Guid?)GetValue(ItemIdProperty); }
set { SetValue(ItemIdProperty, value); }
}
public ReferencedItem()
{
InitializeComponent();
ViewModel = new ReferencedItemCtrlViewModel();
DataContext = ViewModel;
}
ItemsSource 将由 Reference 对象组成,定义为:
public class Reference
{
public Guid Id { get; set; }
}
现在当绑定这个ReferencedItem 时,值没有按预期设置。这是我想要工作的代码,但没有按预期绑定:
<ItemsControl x:Name="ReferenceStack" ItemsSource="{Binding References}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:ReferencedItem ItemId="{Binding Id}" Height="30" HorizontalAlignment="Stretch" VerticalAlignment="Top"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
我试过了:
<local:ReferencedItem ItemId="128d48f0-f061-49fb-af49-b8e4ef891d03" Height="30" HorizontalAlignment="Stretch" VerticalAlignment="Top"/>
这按预期工作,OnItemIdChanged 方法被触发。
<Label Content="{Binding Id}" HorizontalAlignment="Left" VerticalAlignment="Top" Height="30" Width="90"/>
这按预期工作,使用 Id 呈现标签。
这里有什么我遗漏的吗?据我所知,数据在绑定时可用——它只是在我需要它的确切条件下不绑定:)
感谢您的任何意见!
编辑:
这是ReferencedItemList 的代码隐藏,上面发布的第一个 XAML 块:
public partial class ReferencedItemList : UserControl
{
protected ReferencedItemListCtrlViewModel ViewModel;
public ReferencedItemList()
{
InitializeComponent();
ViewModel = new ReferencedItemListCtrlViewModel();
DataContext = ViewModel;
}
public void Load(Guid id, string name)
{
ViewModel.Load(id, name);
//ReferenceStack.ItemsSource = ViewModel.References;
}
}
已尝试使用注释行代替 XAML 中定义的 ItemsSource="{Binding References}"。
我不认为我可以成功发布ReferencedItemListCtrlViewModel 的代码而不进入兔子洞——不用说它具有ObservableCollection<Reference> 类型的属性References,其中Reference 在本文前面定义发帖。
ReferencedItem.xaml:
<v:BaseUserControl.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</v:BaseUserControl.Resources>
<StackPanel Orientation="Horizontal">
<Image x:Name="LinkIcon" Visibility="{Binding HasReference, Converter={StaticResource BooleanToVisibilityConverter}}" ToolTip="View Referenced Item" Source="/Images/link.png" Height="18" MouseUp="LinkIcon_MouseUp"/>
<TextBlock x:Name="ReferencedObjectDesc" Text="{Binding ReferenceHierarchy}" FontStyle="Italic" VerticalAlignment="Center" />
</StackPanel>
【问题讨论】:
-
“值未按预期设置” - 您没有显示用户控件(xaml、构造函数等)。更有可能你在玩它的
DataContext内部,这就是绑定不起作用的原因。检查输出窗口中的绑定错误。 -
这很有帮助 - 它让我对这个问题有了进一步的了解。我对 DataContext 所做的唯一修改是将其分配给要使用的 ViewModel —— 它具有我期望存在的所有属性。我认为它归结为:为什么绑定在标签上起作用,而不是在 ReferencedItem 上?当我检查控制台输出时,出现以下错误: System.Windows.Data Error: 40 : BindingExpression path error: 'Id' property not found on 'object' ''ReferencedItemCtrlViewModel' 这很有帮助 - 但为什么 Label 使用不同的对象并正确绑定?
-
您是说在您的代码中某处设置用户控件的DataContext?我们能看到那段代码吗?
-
正确 - 我更新了我的帖子以包含我设置 DataContext 的代码隐藏。它还让我有机会阅读我的原始帖子,因为它是匆忙输入的,所以我已经清理了一点。感谢您的帮助!
-
ReferencedItem的 Xaml 是什么样的?我们也可以看到它的代码隐藏吗?您是否在代码隐藏中的任何位置设置ItemId,并可能清除绑定?
标签: c# wpf xaml data-binding