无法在usercontrol上显示绑定?

时间:2017-09-26 14:16:51

标签: c# wpf xaml

我无法在usercontrol上显示属性值。 我以这种方式设置了datacontext:

public MainController cm;
public static MainWindow AppWindow;

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

        AppWindow = this;
     }
}

MainController内我所有的控制器都具有以下所有属性:

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

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

现在我已经在不同的控件中拆分了我的用户界面,以便拥有更多的xaml组织。我需要从所有用户控件访问cm的主datacontext,我试过这样:

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

但我明白了:

  

的NullReferenceException

AppWindow上的

。我的主要问题是我无法在用户控件上可用的标签上显示属性的值:

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

这个绑定工作在主窗口但不能处理usercontrol,为什么??

1 个答案:

答案 0 :(得分:0)

假设你有一个这样的窗口:

<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>

然后在构造函数中设置DataContext:

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

现在请记住,DataContext是一个可继承的依赖项属性,即它向下流动。 (通常,依赖项属性默认情况下不可继承,除非您明确说明它)

因此,您在逻辑树(窗口)的根目录上设置一次DataContext,并且其所有子项将“看到”它。 (UniformGrid和我们案例中的自定义控件)

是的,这意味着您可以直接绑定到用户控件的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>

现在,这种方法运行良好,直到您的控件变得如此复杂,以至于它需要分别拥有自己的ViewModel和DataContext。 通常这种情况发生在控件不是被动控件但保持状态(验证输入,按钮状态等)时

1.声明要绑定到主视图模型的所有属性作为依赖项属性,并注意您指定的默认值。

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.现在,您在LayoutRoot上设置DataContext

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

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>

另一种方法是使用RelativeSource进行绑定,但这会破坏UserControl的封装和可重用性。

WPF有一个陡峭的学习曲线,我希望我的建议很有帮助......