简体   繁体   English

无法在用户控件上显示绑定?

[英]Cannot display binding on usercontrol?

I'm not able to display a property value on the usercontrol. 我无法在用户控件上显示属性值。 I set up the datacontext in this way: 我以这种方式设置了数据上下文:

public MainController cm;
public static MainWindow AppWindow;

public partial class MainWindow
{
     public MainWindow()
     {
        InitializeComponent();
        cm = new MainController();
        DataContext = cm;

        AppWindow = this;
     }
}

inside MainController I've all the controller with all the properties like this: MainController内部,我具有所有具有以下所有属性的控制器:

public class MainController: MainControllerVM
{
    private ClubController _clubController = new ClubController();

    public ClubController ClubController 
    {
        get { return _clubController ; }
    }
}

Now I've splitted my user interface in different controls to have more xaml organization. 现在,我已将用户界面拆分为不同的控件,以拥有更多的xaml组织。 I need to access to the main datacontext that's cm from all user controls, I tried in this way: 我需要从所有用户控件访问cm的主数据上下文,我以这种方式尝试过:

public partial class Club : UserControl
{
    public Club ()
    {
        InitializeComponent();
        DataContext = MainWindow.AppWindow.cm;
    }

but I get: 但我得到:

NullReferenceException NullReferenceException

on AppWindow. 在AppWindow上。 My main problem's that I can't get to display the value of the property on a label available on the user control: 我的主要问题是我无法在用户控件上可用的标签上显示属性的值:

<Label Content="{Binding ClubController.Club.Name}" />

this binding working in the main window but not working on usercontrol, why?? 此绑定在主窗口中起作用,但在usercontrol上不起作用,为什么?

Suppose you have a window like this: 假设您有一个这样的窗口:

<Window x:Class="Example.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:Example"
        Title="MainWindow" Height="350" Width="525">
    <UniformGrid Rows="2" Columns="2">
        <local:MyUserControlA/>
        <local:MyUserControlB/>
        <local:MyUserControlC/>
        <local:MyUserControlD/>
    </UniformGrid>
</Window>

And you set the DataContext in the constructor: 然后在构造函数中设置DataContext:

public MainWindow()
{
    InitializeComponent();
    DataContext = this;
}

Now remember that the DataContext is an inheritable dependency property, ie it flows down. 现在请记住,DataContext是可继承的依赖项属性,即它向下流动。 (In general, dependency properties are not inheritable by default, unless you explicitly state it) (通常,除非您明确声明,否则依赖项属性默认情况下不可继承)

So, you set the DataContext once on the root of the logical tree (the window) and all of its children will "see" it. 因此,只需将DataContext设置在逻辑树(窗口)的根上,其所有子级都将“看到”它。 (the UniformGrid and the custom controls in our case) (本例中为UniformGrid和自定义控件)

Yes, that means you can directly bind to the view model in your user control's XAML: 是的,这意味着您可以直接在用户控件的XAML中绑定到视图模型:

<UserControl x:Class="Example.MyUserControlA"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <TextBlock Text="{Binding PropertyFromMainViewModel}"/>      
    </Grid>
</UserControl>

Now, this approach works well, until your control gets so complicated that it needs to have its own ViewModel and DataContext reespectively. 现在,这种方法行之有效,直到您的控件变得如此复杂,以至于需要分别拥有自己的ViewModel和DataContext。 Usually this happens when the control is not a passive, but maintains a state (validates input, button state, etc.) 通常,当控件不是被动控件而是保持状态(验证输入,按钮状态等)时,会发生这种情况

1.Declare all properties that you want to bind to the main view model as dependency properties and pay attention to the default value you specify. 1.将要绑定到主视图模型的所有属性声明为依赖项属性,并注意指定的默认值。

2.Locate the main panel of your UserControl and name it, for example "LayoutRoot": 2.找到您的UserControl的主面板并命名,例如“ LayoutRoot”:

 <UserControl x:Class="Example.MyUserControlA"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid x:Name="LayoutRoot">
        <TextBlock Text="{Binding MyDependencyProperty}"/>      
    </Grid>
</UserControl>

3.Now, you set the DataContext on the LayoutRoot 3.现在,您在LayoutRoot上设置DataContext

public MyUserControlA()
{
    InitializeComponent();
    LayoutRoot.DataContext = new MyUserControlViewModel();
}

4.You bind to the main view model in this way 4.您以这种方式绑定到主视图模型

 <Window x:Class="Example.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:Example"
        Title="MainWindow" Height="350" Width="525">
    <UniformGrid Rows="2" Columns="2">
        <local:MyUserControlA MyDependencyProperty="{Binding MainViewModelProperty}"/>
        <local:MyUserControlB/>
        <local:MyUserControlC/>
        <local:MyUserControlD/>
    </UniformGrid>
</Window>

The other way around is to bind using RelativeSource, but this would break the encapsulation and reusability of your UserControl. 另一种方法是使用RelativeSource进行绑定,但这会破坏UserControl的封装和可重用性。

WPF has a steep learning curve, I hope my tips were helpful... WPF的学习曲线很陡,希望我的技巧对您有所帮助...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM