如何在WPF页网格的数据上下文设置为其他WPF窗口(How to set the data cont

2019-10-18 14:14发布

我是WPF.I有一个WPF窗口,并在同一个项目中,我有一个WPF PAGE电泳页面包含要加载到window.The窗口中的键盘布局有其源设置为page.Now框架的新手在页面中的所有按钮都WPF定制controls.These控件有像IsCapsOn和IsShiftOn两个依赖属性。 上的按钮改变变化的时候,文本这些依赖特性(“a”变为“A”,表示帽被按下)。 上述的依赖特性绑定到由名称IsCapsPressed和IsShiftPressed主窗口的依赖特性。 当用户按下上主窗口帽键,在后端,结果IsCapsOn也有变动,由于此binding.For我必须设置按钮的数据上下文中页到主窗口因为依赖性能列于它定义IsCapsPressed属性更改。以下是代码snipets:

 //page
<Page x:Class="Philips.PmsUS.VirtualKeyboard.Resources.Layouts.USKeyboardPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:kb="clr-namespace:Philips.PmsUS.KeyboardButton;assembly=Philips.PmsUS.KeyboardButton"
      mc:Ignorable="d"
      x:Name="Layout"
      Loaded="Page_Loaded"      
      Title="USKeyboardPage">    
    <Grid x:Name="MainGrid"
          Width="auto"
          Height="auto"
          Focusable="True">
    <!...Row and column definitions are defined...>
     <kb:KeyboardButton Name="Button_Q"
                               Width="auto"
                               Height="auto"
                               Grid.Column="3"                               
                               IsCapsOn="{Binding Path=IsCapsPressed}"
                               IsShiftOn="{Binding Path=IsShiftPressed}"
                               Focusable="True"
                               Style="{StaticResource KeyboardButtonStyle}"
                               Click="NonModifierClick"
                               DataContext="{Binding ElementName=Keyboardwnd}"></kb:KeyboardButton>        
    </Grid>
<page>

//window.xaml
<Window x:Class="Philips.PmsUS.VirtualKeyboard.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"               
        Title="KeyboardWindow"
        x:Name="Keyboardwnd"        
        Height="581"
        Width="1392"
        Topmost="False"
        Loaded="Window_Loaded"
        FocusManager.IsFocusScope="True"
        WindowStartupLocation="Manual"
        Background="{DynamicResource KeyboardBackgroundBrush}">   
    <Grid x:Name="LayoutRoot">
        <Frame x:Name="LayoutHolder"
               Source="Resources\Layouts\USKeyboardPage.xaml"
               ></Frame>            
    </Grid>
  </Window>

//mainwindow.xaml.cs
#region dependency properties
        //the below dependency properties are used for modifier keys
        public static readonly DependencyProperty IsCapsPressedProperty = DependencyProperty.Register("IsCapsPressed", typeof(bool), typeof(MainWindow), new FrameworkPropertyMetadata(new PropertyChangedCallback(SetCapsState)));
        public static readonly DependencyProperty IsShiftPressedProperty = DependencyProperty.Register("IsShiftPressed", typeof(bool), typeof(MainWindow), new FrameworkPropertyMetadata(new PropertyChangedCallback(SetShiftState)));
        public static readonly DependencyProperty IsGlobePressedProperty = DependencyProperty.Register("IsGlobePressed", typeof(bool), typeof(MainWindow), new FrameworkPropertyMetadata(new PropertyChangedCallback(SetGlobeState)));
        #endregion

但上述数据上下文绑定并不是working.Please帮助。

Answer 1:

尝试设置窗口的DataContext。 在窗口的构造函数来完成DataContext = this; InitializeComponents()之后。

谢谢



Answer 2:

不知道问题是什么。
如果你的意思是:

Binding ElementName=Keyboardwnd

这是行不通的作为的ElementName是不是该网页上。

不知道但是把依赖属性,但你可以通过主窗口页面的引用的细节。
不要在XAML设置框架页。
在代码中设置背后,所以你可以保持对它的引用,并通过这一点。

USKeyboardPage uSKeyboardPage;
uSKeyboardPage = new USKeyboardPage(this);
LayoutHolder.Content = uSKeyboardPage;

USKeyboardPage必须有一个构造函数接收主窗口

Public USKeyboardPage(MainWindow main) ...


Answer 3:

我猜你不使用MVVM? 与MVVM一个常见问题是的ViewModels(其有效地保持的观点绑定到数据)之间的通信。 这个问题的一个通用的解决方案是使用消息服务,如包含MVVM光,来发布消息,说一些价值已经更新/动作执行/不管。 有兴趣了解有关的任何其他意见将订阅的消息,然后当它收到,你可以在本地更新的价值。

看不出有任何理由,你不能发布和订阅在后面的代码中的消息,你只需要一个短信服务。



Answer 4:

尼廷这里有一个正确的/部分的答案,但我只是要增加一些色彩,因为你在学习WPF。

要知道这里的关键一点是,从父控件的子控件自动的DataContext级联。

所以我们可以说你有两个的ViewModels,VM1和VM2,以及你有一个WPF的布局是这样的:

Window
- Frame
  - Page
    - Grid
      - KeyboardButton

如果您设置窗口的的DataContext到VM1,然后它会自动向下级联,这样在布局的每个控件都会有指向该VM1实例的DataContext。 如果再设置网格的的DataContext到VM2,然后电网和KeyboardButton会有VM2:

Window                  <- DataContext is VM1, directly set
- Frame                 <- DataContext is VM1, inherited
  - Page                <- DataContext is VM1, inherited 
    - Grid              <- DataContext is VM2, directly set
      - KeyboardButton  <- DataContext is VM2, inherited 

根据您是如何运行的东西,有一个例外 - 框架控件可以打破这种连锁效应,使页面不会继承的DataContext的性质,但是你可以很容易地有框架的代码隐藏明确设置佩奇的DataContext它自己。 第二个答案在这里提供了关于如何做到这一点很容易一个有用的片段:

page.DataContext不从父框架继承?

在任何情况下,如果您设置的DataContext这种方式,它使所有的控制非常简单的布局中进行沟通,因为他们都在看和修改同一个对象的DataContext的(友情提醒:在实施和使用INotifyPropertyChanged接口和属性,使WPF得到通知时,属性变化的价值,它可以自动更新任何绑定到该属性)。

如果你有独立的DataContexts像早期的例子,其中电网得到VM2,你有多种选择,但它在你的项目是如何工作特别依赖。 如果您需要VM2能够与VM1沟通,你可以做一个属性添加到VM2持有VM1,例如。 然而,选择这里真的取决于你是否需要做到这一点,你会怎么需要它的工作。



文章来源: How to set the data context of a grid in a WPF page to an other WPF window