【问题标题】:How to bind to 2 different members in a class in WPF?如何绑定到 WPF 中一个类中的 2 个不同成员?
【发布时间】:2011-03-16 21:46:27
【问题描述】:

我有这样的课:

class EditorViewModel
{
    public ObservableCollection<Effect> AllEffects;
    public bool HasPermissions;
}

但问题是,当我尝试将AllEffects 绑定到ListView 时,我无法将任何内容绑定到HasPermissions,因为绑定范围仅限于AllEffects,而不是EditorViewModel

我试过了,但它不起作用:

<ListView ItemsSource="{Binding EditorViewModel}">

...

<GridViewColumn Width="Auto" Header="Name">
    <GridViewColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding AllEffects.Name}"/>
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>

<GridViewColumn Width="Auto" Header="Type">
    <GridViewColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding AllEffects.Type}"/>
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>

如果我将ItemsSource 设置为EditorViewModel 并去掉AllEffects,它就可以工作。但是后来我不知道如何通过绑定访问HasPermissions

<GridViewColumn Width="50" Header="Override">
    <GridViewColumn.CellTemplate>
        <DataTemplate>
            <CheckBox Margin="0"
                                    HorizontalAlignment="Center"
                                    IsEnabled="{Binding HasPermission}"/>
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>

【问题讨论】:

    标签: c# .net wpf listview


    【解决方案1】:

    当我更新我的答案 on this question 以包含时,您可以将 ListView 绑定到 ViewModel 的 AllEffects 属性,然后使用 relative 绑定引用 ViewModel 的不同属性。因此,假设您的 ListView 包含在 Window 中,其 DataContextEditorViewModel,并且 ListView 的 ItemsSource 是 AllEvents,您仍然可以像这样引用 HasPermission:

    <CheckBox Margin="0"
              HorizontalAlignment="Center"
              IsEnabled="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.HasPermission}"/>
    

    这个有点笨拙的符号会在可视化树中找到最接近 CheckBox 的父元素,它是 Window 类型,并绑定到它的 DataContext 属性以找到 HasPermission。

    【讨论】:

    • 谢谢,哇,我很惊讶。这是怎么做的?所以它不能像我在我的问题中展示的那样做吗?我问的原因是MS是否主要考虑了这些情况?或者这是一个角落案例?顺便说一句,我不是在批评你的方法,只是想理解它。再次感谢。
    • 我试过你的方法,但它说,在RelativeSource类型中找不到路径。是因为我在窗口顶部有 DataContext="{Binding RelativeSource={RelativeSource Self}}" 吗?
    • MS 在开始实施 WPF 时并没有过多考虑 MVVM。后来它出现了 :) 只有 wpf/silverlight 5 将针对 mvvm。
    • 我以为 MS 建议大家使用 MVVM?如果不是用于 WPF 的 MVVM,那么您应该使用它什么? WPF 5 是否会更轻松、更好地处理所有这些事情?
    • MS 现在建议这样做,但据我所知,MVVM 并不是来自 MS,而是来自社区。人民的力量!
    【解决方案2】:

    一个经典的技巧是使用 ViewModelLocator,参见: MVVM Light - using ViewModelLocator - properties hit multiple times

    此外,对于更快速和更脏的解决方案,您可以使用以下绑定:

    {Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView}, Path=DataContext.HasPermissions}
    

    请注意,这仅适用于 WPF 而不适用于 SL,因为 SL 不支持 RelativeSource 的这种语法。

    【讨论】:

    • 谢谢,我不知道如何使用 ViewModelLocator。看起来很先进,不是吗?
    • 其实非常简单.. google一下google.com/…
    • 谢谢,顺便说一句,你知道它为什么这么复杂/复杂吗?因为 Locator 听起来像是必须定位某些东西,但我已经知道它在哪里,如果 WPF 有办法让我像使用单个成员数据绑定一样指定。
    • 如果你愿意,你也可以使用RelativeSource Binding。我会更新我的答案。
    • np :) 我仍然建议您尝试了解 ViewModelLocator - 这是我每次执行 MVVM 时都会实施的一个很棒的模式,它有很多好处。
    猜你喜欢
    • 2011-10-12
    • 1970-01-01
    • 2019-10-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-13
    • 1970-01-01
    • 2020-12-31
    • 1970-01-01
    相关资源
    最近更新 更多