0

I have a WPF form with a content control and a custom control. The content control swaps in views based on a radio button selection. Once the user takes an action on the view, I set the nocustomer on the parent viewmodel (the WPF form containing the two controls) to false. When this occurs, the visibility of content control correctly disappears. Unfortunately, the visibility of the custom control remains unchanged (it should have also disappeared). I'm actually perplexed because in my mind they have the exact same implementation and therefore should behave the same.

<ContentControl x:Name="ViewSwap" Content="{Binding SearchingViewModel}" 
Visibility="{Binding NoCustomer, Converter={StaticResource 
BooleanToVisibilityConverter}, Mode=OneWay}">
    <ContentControl.Style>
        <Style TargetType="{x:Type ContentControl}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding ElementName=SearchOptions, Path=IsSelected}" Value="0">
                    <Setter Property="ContentTemplate" Value="{StaticResource AddressTemplate}" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ContentControl.Style>
</ContentControl>

<views:CTACallSubmit x:Name="CallSubmit" 
Visibility="{Binding NoCustomer, Converter={StaticResource 
BooleanToVisibilityConverter}, Mode=OneWay}"/>

Update:

MainWindow's DataContext

public partial class CTALight : Window
{
    public CTALight()
    {
        InitializeComponent();

        this.DataContext = CTALightViewModel.GetInstance();
    }
}

MainViewModel

 public class CTALightViewModel : ObservableObject
 {
    public static CTALightViewModel _mainViewModel;

    public static CTALightViewModel GetInstance()
    {
        if (_mainViewModel == null)
            _mainViewModel = new CTALightViewModel();          

        return _mainViewModel;
    }

    private CTALightViewModel()
    {
    }

}

CTACallSubmit DataContext

<UserControl.DataContext>
    <viewmodel:CTACallSubmitViewModel />
</UserControl.DataContext>
GregN
  • 142
  • 1
  • 13
  • Do they have the same DataContext? Are you explicitly setting the DataContext of CTACallSubmit somewhere? – mm8 Feb 28 '18 at 20:47
  • Updated. Based on your question I assume I need to explicitly say where nocustomer lives. In this case, it would be the datacontext of the window that I bind to pass the data to the property of the usercontrol (visibility). – GregN Feb 28 '18 at 21:15
  • When you explicitly set a UserControl's DataContext to a CTACallSubmitViewModel instance, a Binding like `` expects the NoCustomer property in the CTACallSubmitViewModel instance. This is probably not what you want. You should usually not explicitly set a UserControl's DataContext, but use the one inherited from the parent control. – Clemens Feb 28 '18 at 21:20
  • What happens if there is functionality (i.e., loading additional fields from a drop down box) that are specific to the user control but not specific to the parent control? – GregN Feb 28 '18 at 21:37

1 Answers1

1

The following creates a new instance of CTACallSubmitViewModel and sets the DataContext of the UserControl to this one.

<UserControl.DataContext>
    <viewmodel:CTACallSubmitViewModel />
</UserControl.DataContext>

This means that the binding to the NoCustomer property of the other view model won't work unless you specify a source of the binding:

<views:CTACallSubmit x:Name="CallSubmit" 
        Visibility="{Binding DataContext.NoCustomer, 
        RelativeSource={RelativeSource AncestorType=Window}, 
        Converter={StaticResource BooleanToVisibilityConverter}, Mode=OneWay}"/>

Setting the DataContext of a UserControl like this is usually a bad idea as it breaks the inheritance of the parent's DataContext.

mm8
  • 163,881
  • 10
  • 57
  • 88
  • What would be the proper way of setting the datacontext for the usercontrol? – GregN Feb 28 '18 at 21:22
  • The proper way would be to let it inherit the DataContext from the parent window, just like the ContenControl does. – mm8 Feb 28 '18 at 21:23
  • Yeah I planned to upvote but wanted to check some other things out. I get an error saying that relativesource is not in find ancestor mode. I assume I need to search for a type? Also what throws me off is the content control just swaps datatemplates to other usercontrols that are bound the exact same way. I would have assumed it would have also broke it. – GregN Feb 28 '18 at 21:30
  • Getting a xaml error that says: "RelativeSource is not in find ancestor mode" – GregN Feb 28 '18 at 21:46
  • Did you really copy my sample markup? It compiles just fine in a WPF application. Did you try to build? – mm8 Feb 28 '18 at 21:58
  • Looks like I had to run clean on the solution. Build was fine. Just pesky xaml editor. – GregN Feb 28 '18 at 22:56