简体   繁体   English

用户控件的数据上下文是什么?

[英]What is the datacontext of the user control?

I have a user control like so: 我有这样的用户控件:

 <Grid>

    <StackPanel Orientation="Vertical">
        <TextBlock Text="{Binding NameC}" Width="100" />
        <TextBlock Text="{Binding Filename}"  />
    </StackPanel>

</Grid>

with DP in code behind: 在DP后面的代码中:

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


    public static readonly DependencyProperty NameCProperty = DependencyProperty.Register(
        "NameC", typeof(string), typeof(TestUc), new PropertyMetadata(default(string)));

    public string NameC
    {
        get { return (string) GetValue(NameCProperty); }
        set { SetValue(NameCProperty, value); }
    }


    public static readonly DependencyProperty FilenameProperty = DependencyProperty.Register(
        "Filename", typeof (string), typeof (TestUc), new PropertyMetadata(default(string)));

    public string Filename
    {
        get { return (string) GetValue(FilenameProperty); }
        set { SetValue(FilenameProperty, value); }
    }

Now, when using it in a window, 现在,在窗口中使用它时,

this works fine: 这工作正常:

<Window x:Class="TestDpOnUc.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:uc="clr-namespace:TestDpOnUc"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <uc:TestUc NameC="name is xxx" Filename="This is filename" />
</Grid>

But This does not: 但这不是:

<Window x:Class="TestDpOnUc.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:uc="clr-namespace:TestDpOnUc"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <uc:TestUc NameC="{Binding Name}" Filename="{Binding FileName}" />
</Grid>

public MainWindow()
    {
        InitializeComponent();

        DataContext = this;

        Name = "name is nafsafd";
        FileName = "lkjsfdalkf";


    }

    private string _Name;

    public string Name
    {
        get { return _Name; }
        set
        {
            _Name = value; 
            OnPropertyChanged();
        }
    }


    private string _FileName;

    public string FileName
    {
        get { return _FileName; }
        set
        {
            _FileName = value;
            OnPropertyChanged();
        }
    }

Can someone please explain why? 有人可以解释为什么吗? Why is the datacontext of the user control not automatically set to the parent - the main window? 为什么用户控件的数据上下文未自动设置为父窗口-主窗口?

It's because of this line DataContext = this in UserControl constructor. 这是因为UserControl构造函数中的这一行DataContext = this You set DataContext to your user control which affects default binding context for TestUc and all children, including <uc:TestUc ... /> . 您将DataContext设置为用户控件,这会影响TestUc和所有子级(包括<uc:TestUc ... />默认绑定上下文。 So at the moment 所以目前

<uc:TestUc NameC="{Binding Name}" Filename="{Binding FileName}" />

will look for Name and FileName properties inside UserControl . 将在UserControl查找NameFileName属性。 You need to remove that line but that will break bindings within the user control. 您需要删除该行,但这会破坏用户控件中的绑定。

<TextBlock Text="{Binding NameC}" Width="100" />
<TextBlock Text="{Binding Filename}"  />

Will look for NameC and Filename in MainWindow . 将在MainWindow查找NameCFilename Solution to that is to change binding context, per binding, via either RelativeSource or ElementName binding inside UserControl 解决方案是通过UserControl内部的RelativeSourceElementName绑定来更改每个绑定的绑定上下文

<UserControl ... x:Name="myUserControl">
    <Grid>
        <StackPanel Orientation="Vertical">
            <TextBlock Text="{Binding ElementName=myUserControl, Path=NameC}" Width="100" />
            <TextBlock Text="{Binding ElementName=myUserControl, Path=Filename}"  />
        </StackPanel>
    </Grid>
</UserControl>

When creating a UserControl with DependencyProperties you have to bind your DP's within your UserControl with ElementName- or RelativeSource Binding to your Controls in your UserControl 创建具有DependencyProperties的UserControl时,必须将ElementName或RelativeSource绑定到UserControl中的DP绑定到UserControl中的控件

<TextBlock Text="{Binding ElementName=myUserControl, Path=NameC}" Width="100" />

and you never set the DataContext. 而且您永远不会设置DataContext。

DataContext = this; <-- do not do that within your UserControl

When you wanna use your UserControl you put it in your View and bind the Properties of your actual DataContext/Viewmodel to the DependencyProperties of the UserControl. 当您要使用UserControl时,请将其放在View中,然后将实际DataContext / Viewmodel的Properties绑定到UserControl的DependencyProperties

<uc:TestUc NameC="{Binding Name}" Filename="{Binding FileName}" />

Whe you are doing <uc:TestUc NameC="{Binding Name}" Filename="{Binding FileName}" /> its not looking at MainWindow's data context instead at your UserControl's data context. 在执行<uc:TestUc NameC="{Binding Name}" Filename="{Binding FileName}" />它不查看MainWindow的数据上下文,而是查看UserControl的数据上下文。

So you might want to search for the right element and bind it. 因此,您可能想搜索正确的元素并将其绑定。 Below is one way to do it using ElementName by giving a name to Window like MainWindowName . 下面是使用ElementName的一种方法,即为Window命名,例如MainWindowName Or you can also use relative source to search for its ancestor. 或者,您也可以使用相对源来搜索其祖先。

<Window x:Class="TestDpOnUc.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:uc="clr-namespace:TestDpOnUc"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525"
    x:Name="MainWindowName">
<Grid>
    <uc:TestUc NameC="{Binding Element=MainWindowName, Path=DataContext.Name}" Filename="{Binding Element=MainWindowName, Path=DataContext.FileName}" />
</Grid>

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

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