【问题标题】:wpf binding upwards: bind to view model property inside nested uiElementwpf 向上绑定:绑定到嵌套 uiElement 内的视图模型属性
【发布时间】:2021-02-01 10:36:50
【问题描述】:

我有一个带有视图模型和一些嵌套 UI 元素的 WPF 项目。这是 XAML 的(相关部分):

<UserControl> // DataContext is MyVM (set programmatically)
    <TreeView ItemsSource="{Binding Trees}">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Subtrees}">
                <StackPanel>
                    <ListView ItemsSource="{Binding Contents}"
                              SelectedValue="{Binding SelectedContent}" // won't work: Tree has no such property
                              SelectionMode="Single"/>
                </StackPanel>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>
</UserControl>

ViewModel 类的代码如下:

public class MyVM : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string name = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }

    public IEnumerable<Tree> Trees { get; set; }

    private object _selectedContent;
    public string SelectedContent
    {
        get => _selectedContent;
        set
        {
            _selectedContent = value;
            OnPropertyChanged();
        }
    }
}

这里是Tree类的代码:

public class Tree
{
    public IEnumerable<Tree> Subtrees { get; set; }
    public IEnumerable<string> Contents { get; set; }
}

我只想在全局范围内为所有 ListViews 选择一个选项。就像here一样,我想将所有ListViews绑定到视图模型MyVM中的属性SelectedContent

问题在于ListView 的数据上下文是Tree,而不是来自顶级用户控件的MyVM。 (应该是Tree,因为我们要显示Contents。)我知道我可以使用SelectedValuePath 向下绑定,但是我如何向上绑定以将SelectedValue 绑定到MyVM 属性SelectedContent?

我试过SelectedValue="{Binding RelativeSource={RelativeSource AncestorType ={x:Type UserControl}}, Path=SelectedContent}",但没用。

【问题讨论】:

    标签: c# wpf data-binding


    【解决方案1】:

    尝试使用

    SelectedValue="{Binding RelativeSource={RelativeSource 
      Mode=FindAncestorBindingContext, AncestorType ={x:Type MyVM}}, 
      Path=SelectedContent}"
    

    也许,您需要在标题中描述模型的命名空间:

    xmlns:viewmodel="clr-namespace:_your_namespace_.ViewModels"
    

    并使用

    SelectedValue="{Binding RelativeSource={RelativeSource 
      Mode=FindAncestorBindingContext, AncestorType ={x:Type viewmodel:MyVM}}, 
      Path=SelectedContent}"
    

    【讨论】:

      【解决方案2】:

      有评论here,说:

      这里只是想说明一下,如果你想绑定到 如果是 RelativeSource 的 DataContext,那么您必须明确指定它: {绑定路径=DataContext.SomeProperty,RelativeSource=....这是 作为一个新手,当我试图绑定到一个 DataTemplate 中父级的 DataContext。

      此评论值得更多关注,因此我将其用作正确答案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-16
        • 2010-11-01
        • 1970-01-01
        • 2010-12-09
        • 1970-01-01
        • 2023-03-06
        • 1970-01-01
        • 2013-02-14
        相关资源
        最近更新 更多