【问题标题】:XAML inconsistent bindingXAML 不一致的绑定
【发布时间】: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&lt;Reference&gt; 类型的属性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


【解决方案1】:

我只是想发布我遇到的答案(解释)。

问题是在构造函数中更改了我的ReferencedItem 用户控件的DataContext。该视图将实例化一个ReferencedItem 并更改DataContext - 所以一旦到了绑定的时间,我已经从预期的Reference 翻转了上下文。

有多种方法可以解决时间问题 - 都取决于项目。避免将 DataContext 设置在一起,将其设置为绑定后,或根据需要更改其他项目的上下文。

非常感谢SinatrAndrew StephensMike Strobel 在某个时间点提到这一点——我花了一些时间才真正了解它。我认为没有办法为评论分配功劳,但如果有,请告诉我。

【讨论】:

    猜你喜欢
    • 2020-01-26
    • 2013-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多