WPF:将页面控件绑定到父窗口的属性

时间:2018-01-05 13:36:54

标签: c# asp.net wpf xaml data-binding

好的,所以我想将TextBlock控件的Foreground属性绑定到MainWindow的代码隐藏中的属性。控件位于MainWindow框架中加载的页面上。我已经尝试了一些东西,但我认为应该工作的绑定,如所示,不会。

主窗口和Page xaml:

<MainWindow>
    <Frame></Frame>
</MainWindow>

<Page>
    <TextBlock Foreground="{Binding RelativeSource={
        RelativeSource FindAncestor, AncestorType={
        x:Type local:MainWindow}}, Path=TextBrush}" />
    <!-- or Foreground="{Binding TextBrush, RelativeSource={
        RelativeSource FindAncestor, AncestorType={
        x:Type local:MainWindow}}}" /> -->
</Page>

主窗口代码隐藏:

public partial class MainWindow : INotifyPropertyChanged {
private Brush _textBrush;
public Brush TextBrush
    {
        get => _textBrush;
        set
        {
            _textBrush = value;
            OnPropertyChanged("TextBrush");
        }
    }

public ICommand SwitchToDarkmodeCommand
    {
        get
        {
            return new DelegateCommand(() =>
            {
                TextBrush = Brushes.White;
                BackgroundBrush = (Brush)new BrushConverter().ConvertFromString("#D2D2D2");
            });
        }
    }

看起来太简单了。我在这里做错了什么?

编辑:输出。好点。

System.Windows.Data Error: 4 : Cannot find source for binding with reference 
'RelativeSource FindAncestor, AncestorType='AddINDesignerWPF.MainWindow', AncestorLevel='1''. 
BindingExpression:Path=TextBrush; DataItem=null; target element is 'TextBlock' (Name=''); 
target property is 'Foreground' (type 'Brush')

2 个答案:

答案 0 :(得分:0)

尝试使用依赖属性而不是普通属性:

  public static readonly DependencyProperty TextBrushProperty =
  DependencyProperty.Register("TextBrush", typeof(Brush), typeof(MainWindow), new UIPropertyMetadata());

public Brush TextBrush
{
    get { return (Brush)this.GetValue(TextBrushProperty); }
    set { this.SetValue(TextBrushProperty, value); }
}

答案 1 :(得分:0)

我只花了一些时间查看反编译的WPF代码,绑定失败的原因是,当从Page中的TextBlock向上走时,可视树以某种方式停止在帧之前。因此,与FindAncestor的RelativeSource绑定无法找到源属性,无论它是依赖项还是INPC属性,无论您是使用Window还是MainWindow作为Type。

此行为的原因可能是帧控件将其内容与应用程序的其余部分隔离,因为它适用于您可能不信任的外部内容。 This SO post提供了更多信息,还提供了如何将数据上下文传递到框架中的页面的解决方案。

也就是说,根据您想要实现的目标,您可能根本不使用框架/页面。