【问题标题】:WPF Binding two dependency properties of the same control but two datacontexts neededWPF绑定同一个控件的两个依赖属性,但需要两个数据上下文
【发布时间】:2015-01-20 11:48:40
【问题描述】:

我在一个网格中有两个控件。

   <TextBlock Text="{Binding Name}" TextAlignment="Center" />
   <TextBox Visibility="{Binding ElementName=EditMode,Source={Binding RelativeSource=
                   {RelativeSource FindAncestor, AncestorType={x:Type Window}}}, 
                   Converter={StaticResource BoolToVis}}"  Text="{Binding Name}" 
                   TextAlignment="Center" />

我正在尝试实现类似可编辑/不可编辑的行为。我知道我可能会选择 TextBox 并简单地更改 IsEditable 属性,但在我的场景中,我仍然需要 DataContext,至少我是这么想的。

在我的示例中,TextBlock 工作正常,TextBox 上的 Text 属性也工作正常,但对于 Visibility 部分,我想绑定到某个其他层上的数据属性( EditMode 是一个布尔值)。有没有办法将 DataContext 更改为此,但仅适用于 Visibility ? Text 属性应保持原样。

我是否应该尝试破解,定义一个不可见的复选框,在单击我的编辑按钮时更改 IsChecked 并直接绑定到该复选框?我会试试这个。我认为这样,不需要更改 DataContext。

【问题讨论】:

  • 为什么不把EditMode属性放到当前数据上下文中?
  • &lt;TextBox Visibility="{Binding ElementName=EditMode, Converter={StaticResource BoolToVis}}" /&gt;怎么样
  • @Denis,如果我把它放在那里,我将进行一些集合迭代,以便在单击“编辑”按钮时更改它。这就是为什么我试图将它保持在更高的水平,这意味着在我的窗口的数据上下文中。
  • @rraszewski 通过这样做,我使用了错误的数据上下文,即用于 Text 属性的数据上下文。
  • 遵循 MVVM 将使结构更加清晰:视图模型(数据内容事物)应该提供通用视图能够表示数据的所有必要属性。如果您缺少一个,那么只需添加它。您可以将属性Name 绑定到TextBlock.Text 和属性IsNameEditable(或其他)用于Visibility。最后一个甚至可以是Visibility 类型,以避免有转换器的必要性。这样,您将拥有相同 data-content 中的所有属性 - 没问题。

标签: c# wpf


【解决方案1】:

@FrumRoll 是正确的,您可以使用 RelativeSource Binding 访问不在集合 DataContext 对象中的属性。但是,我不确定他们的代码是否完全正确......试试这个:

<TextBox Visibility="{Binding DataContext.EditMode, RelativeSource={RelativeSource 
    AncestorType={x:Type YourXamlPrefix:MainWindow}}}, Converter={StaticResource 
    BoolToVis}}" Text="{Binding Name}" TextAlignment="Center" />

显然,您需要将 YourXamlPrefix 值更改为本地 XAML 命名空间前缀,并使用 Window 的名称/类型更改 MainWindow(如果不称为 MainWindow)。这还假设您的 EditMode 属性已在该 Window 中定义。

可能也可以,但不是专门寻找你的确切Window,所以可能有一些问题:

<TextBox Visibility="{Binding DataContext.EditMode, RelativeSource={RelativeSource 
    AncestorType={x:Type Window}}}, Converter={StaticResource BoolToVis}}" 
    Text="{Binding Name}" TextAlignment="Center" />

【讨论】:

    【解决方案2】:

    在我看来,您已经快到了,您应该可以使用 RelativeSource 来执行此操作。问题是您误用了 ElementName,ElementName 是绑定到命名源的属性,将被用来代替 RelativeSource。您打算使用的是 Path,它是可选的,如下所示。

    <TextBox Visibility="{Binding DataContext.EditMode, RelativeSource={RelativeSource AncestorType={x:Type Window}}, 
                   Converter={StaticResource BoolToVis}}"
             Text="{Binding Name}" TextAlignment="Center" />
    

    【讨论】:

    • 确实这看起来不错,但我收到此错误:无法在“绑定”类型的“源”属性上设置“绑定”。只能在 DependencyObject 的 DependencyProperty 上设置“绑定”。
    • 您应该删除“Source={Binding”和结尾的“}”。设置 Source 或 RelativeSource,而不是像您那样设置两者。
    • @RobvanDaal 这是正确的,我在复制 OP 时错过了这个错误。我已经修正了语法。
    猜你喜欢
    • 2011-12-03
    • 2018-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-30
    相关资源
    最近更新 更多