My WPF custom control's Data Context is superseding parent's

三世轮回 提交于 2019-12-01 05:55:13

That is one of the many reasons you should never set the DataContext directly from the UserControl itself.

When you do so, you can no longer use any other DataContext with it because the UserControl's DataContext is hardcoded in.

In the case of your binding, normally the DataContext would be inherited so the Visibility binding could find the property MyControlVisible on the current DataContext, however because you hardcoded the DataContext in your UserControl's constructor, that property is not found.

You could specify a different binding source in your binding, such as

<Controls:MyUserControl Visibility="{Binding 
    RelativeSource={RelativeSource AncestorType={x:Type Window}}, 
    Path=DataContext.MyControlVisible, 
    Converter={StaticResource boolToVis}}" ... />

However that's just a workaround for the problem for this specific case, and in my view is not a permanent solution. A better solution is to simply not hardcode the DataContext in your UserControl

There are a few different ways you can do depending on your UserControl's purpose and how your application is designed.

  • You could create a DependencyProperty on your UserControl to pass in the value, and bind to that.

    <Controls:MyUserControl UcModel="{Binding MyUControlModelProperty}" ... />
    

    and

    <UserControl x:Class="Sandbox.Controls.MyUserControl"
                 ElementName=MyUserControl...>
        <Grid DataContext="{Binding UCModel, ElementName=MyUserControl}">
            <TextBlock Text="{Binding MyBoundText}"/>
        </Grid>
    </UserControl>
    
  • Or you could build your UserControl with the expectation that a specific property will get passed to it in the DataContext. This is normally what I do, in combination with DataTemplates.

    <Controls:MyUserControl DataContext="{Binding MyUControlModelProperty}" ... />
    

    and

    <UserControl x:Class="Sandbox.Controls.MyUserControl"...>
        <Grid>
            <TextBlock Text="{Binding MyBoundText}"/>
        </Grid>
    </UserControl>
    
  • As I said above, I like to use DataTemplates to display my UserControls that expect a specific type of Model for their DataContext, so typically my XAML for the main window would look something like this:

    <DataTemplate DataType="{x:Type local:MyUControlModel}">
        <Controls:MyUserControl />
    </DataTemplate>
    
    <ContentPresenter Content="{Binding MyUControlModelProperty}" ... />
    
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!