Bind Dependency property defined in Code-Behind through Xaml for property in DataContext UserControl

I want to use code similar to the one found here. The problem I'm running into is that I would like to expand it to allow the value set in XAML to be used {Binding PropertyOfViewModel}

like this:

<local:TestControl>
  <local:TestControl.TestObject>
    {Binding PropertyOfViewModel}
  </local:TestControl.TestObject>
</local:TestControl>

      

The problem is that these are errors with "Can not Convert" {Binding PropertyOfViewModel} "". The TestObject property is defined as a dependency property in the code for the view.

If I can get it to work, it will allow me to write code like this in the parent control:

<local:TestControl x:Name="myControl" DataContext="{Binding TCViewModel}" />

      

This means that in the UserControl I can also bind to commands and other items open in my TCViewModel and the control can be mostly self contained and all the consumer needs is the DataContext property.


change

This is the whole control:

<UserControl x:Class="MyProject.Views.AddClientView"
         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" 
         xmlns:Views="clr-namespace:MyProject.Views"
         Background="{StaticResource WindowBackgroundBrush}"
         mc:Ignorable="d">

<!-- Comment out from here
   <Views:AddClientView>
    <Views:AddClientView.RenderTransform>
        <ScaleTransform ScaleY="1" />
    </Views:AddClientView.RenderTransform>
    <Views:AddClientView.IsInAcceptDataMode>
        <Binding Path="IsInInputMode"/>
    </Views:AddClientView.IsInAcceptDataMode>
    <Views:AddClientView.ContentTemplate>
        <DataTemplate>
to here -->
            <Grid>
                <Label 
                    Height="25" 
                    Width="306"
                    HorizontalAlignment="Left" 
                    Margin="12,12,0,0" 
                    OverridesDefaultStyle="False" 
                    Style="{DynamicResource CalloutLabel}" 
                    VerticalAlignment="Top" Content="Company Name (Name of Organizational Unit)"/>

                <TextBox Height="23" Margin="12,41,12,0" VerticalAlignment="Top" TabIndex="1" />

                <Button 
                    Style="{DynamicResource LightButton}" 
                    Height="23" Width="75" 
                    HorizontalAlignment="Right" 
                    VerticalAlignment="Bottom" 
                    Margin="0,0,97,12" 
                    TabIndex="4">OK</Button>

                <Button 
                    Style="{DynamicResource LightButton}" 
                    Height="23" Width="75" 
                    HorizontalAlignment="Right" 
                    VerticalAlignment="Bottom" 
                    Margin="0,0,12,12" 
                    Command="{Binding Cancel}"
                    TabIndex="3">Cancel</Button>

                <CheckBox Content="Make Groups" Height="16" IsChecked="True" FlowDirection="RightToLeft" Margin="150,79,12,0" VerticalAlignment="Top" TabIndex="2" />

                <Rectangle Fill="{DynamicResource HeaderBarFill}" Height="5" Margin="0,0,0,0" Stroke="{x:Null}" VerticalAlignment="Bottom" />
            </Grid>
<!-- and here 
        </DataTemplate>
    </Views:AddClientView.ContentTemplate>
</Views:AddClientView>
to here-->

      

To get it to compile with the suggested code, I had to reorder my xaml, now it simultaneously crashes Visual Studio in design mode and when I run it I get a StackOverflow exception InitializeComponent();

in the view designer.


change 2

This is the code that puts this UserControl on the window:

<Views:AddClientView x:Name="AddClient" VerticalAlignment="Top" DataContext="{Binding AddClientVM}">
</Views:AddClientView>

      

Interesting: If I remove this code from the window, it runs / compiles OK. If I remove all of the type code <Views:AddClientView...>

from the view, it also works fine. But doesn't do what I want, because I can't bind my DP to the DataContext.

If I change the UserControl to below everything compiles fine, I just lose my code dependency property binding:

<UserControl 
    x:Class="Mage.Views.AddClientView"
    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" 
    xmlns:Views="clr-namespace:Mage.Views"
    Background="{StaticResource WindowBackgroundBrush}"
    mc:Ignorable="d"  d:DesignWidth="320" d:DesignHeight="145"
    x:Name="AddClientV"
    MaxHeight="145" MinHeight="145">

    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup>
            <VisualState x:Name="Show">
                <VisualState.Storyboard>
                    <Storyboard>
                    <DoubleAnimation 
                            Storyboard.TargetProperty="RenderTransform.(ScaleTransform.ScaleY)" 
                            Storyboard.TargetName="AddClientV" 
                            From="0" 
                            To="1" 
                            Duration="0:0:1" />
                    </Storyboard>
                </VisualState.Storyboard>
            </VisualState>

            <VisualState x:Name="Hide">
                <VisualState.Storyboard>
                    <Storyboard>
                    <DoubleAnimation 
                        Storyboard.TargetProperty="RenderTransform.(ScaleTransform.ScaleY)" 
                        Storyboard.TargetName="AddClientV" 
                        From="1" 
                        To="0" 
                        Duration="0:0:1" />
                    </Storyboard>
                </VisualState.Storyboard>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>

    <Views:AddClientView>
        <Views:AddClientView.RenderTransform>
            <ScaleTransform ScaleY="1" />
        </Views:AddClientView.RenderTransform>
        <Views:AddClientView.IsInAcceptDataMode>
            <Binding Path="IsInInputMode"/>
        </Views:AddClientView.IsInAcceptDataMode>
        <Views:AddClientView.ContentTemplate>
            <DataTemplate>
                <Grid>
                    <Label 
                        Height="25" 
                        Width="306"
                        HorizontalAlignment="Left" 
                        Margin="12,12,0,0" 
                        OverridesDefaultStyle="False" 
                        Style="{DynamicResource CalloutLabel}" 
                        VerticalAlignment="Top" Content="Company Name (Name of Organizational Unit)"/>

                    <TextBox Height="23" Margin="12,41,12,0" VerticalAlignment="Top" TabIndex="1" />

                    <Button 
                        Style="{DynamicResource LightButton}" 
                        Height="23" Width="75" 
                        HorizontalAlignment="Right" 
                        VerticalAlignment="Bottom" 
                        Margin="0,0,97,12" 
                        TabIndex="4">OK</Button>

                    <Button 
                        Style="{DynamicResource LightButton}" 
                        Height="23" Width="75" 
                        HorizontalAlignment="Right" 
                        VerticalAlignment="Bottom" 
                        Margin="0,0,12,12" 
                        Command="{Binding Cancel}"
                        TabIndex="3">Cancel</Button>

                    <CheckBox Content="Make Groups" Height="16" IsChecked="True" FlowDirection="RightToLeft" Margin="150,79,12,0" VerticalAlignment="Top" TabIndex="2" />

                    <Rectangle Fill="{DynamicResource HeaderBarFill}" Height="5" Margin="0,0,0,0" Stroke="{x:Null}" VerticalAlignment="Bottom" />
                </Grid>
            </DataTemplate>
        </Views:AddClientView.ContentTemplate>
    </Views:AddClientView>
</UserControl>

      

Code Dependency property:

    public bool IsInAcceptDataMode
    {
        get { return (bool)GetValue(IsInAcceptDataModeProperty); }
        set 
        {
            SetValue(IsInAcceptDataModeProperty, value); 

            if (value)
            {
                VisualStateManager.GoToState(this, "Show", false);
            }
            else
            {
                VisualStateManager.GoToState(this, "Hide", false);
            }
        }
    }

    public static readonly DependencyProperty IsInAcceptDataModeProperty =
        DependencyProperty.Register("IsInAcceptDataMode", typeof(bool), typeof(AddClientView), new UIPropertyMetadata(false, null));

      


change 3

So, I was informed that there are XAML based binding issues, I tried to translate the code into code and I still can't get it to work. So, I'm looking at this point for a coding-based way of binding my DependencyProperty to an element in the ViewModel that is specified in the DataContext of my UserControl.

+1


source to share


1 answer


If I understood everything correctly, then you need a standard MVVM script and standard bindings.

You can do it like this:

<local:TestControl TestObject="{Binding PropertyOfViewModel}">
</local:TestControl>

      

Or like this:



<local:TestControl>
  <local:TestControl.TestObject>
    <Binding Path="PropertyOfViewModel"/>
  </local:TestControl.TestObject>
</local:TestControl>

      

Update: In response to the code of yours UserControl

you provided ...

What you are doing is placing the control inside itself, which will obviously give you a StackOverflow exception. You don't need to define ContentTemplate

internally UserControl

. You can simply place content directly as a child:

<UserControl 
    x:Class="Mage.Views.AddClientView"
    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" 
    xmlns:Views="clr-namespace:Mage.Views"
    Background="{StaticResource WindowBackgroundBrush}"
    mc:Ignorable="d"  d:DesignWidth="320" d:DesignHeight="145"
    x:Name="AddClientV"
    MaxHeight="145" MinHeight="145">

    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup>
            <VisualState x:Name="Show">
                <VisualState.Storyboard>
                    <Storyboard>
                    <DoubleAnimation 
                            Storyboard.TargetProperty="RenderTransform.(ScaleTransform.ScaleY)" 
                            Storyboard.TargetName="AddClientV" 
                            From="0" 
                            To="1" 
                            Duration="0:0:1" />
                    </Storyboard>
                </VisualState.Storyboard>
            </VisualState>

            <VisualState x:Name="Hide">
                <VisualState.Storyboard>
                    <Storyboard>
                    <DoubleAnimation 
                        Storyboard.TargetProperty="RenderTransform.(ScaleTransform.ScaleY)" 
                        Storyboard.TargetName="AddClientV" 
                        From="1" 
                        To="0" 
                        Duration="0:0:1" />
                    </Storyboard>
                </VisualState.Storyboard>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>

    <Views:AddClientView.RenderTransform>
            <ScaleTransform ScaleY="1" />
    </Views:AddClientView.RenderTransform>
    <Views:AddClientView.IsInAcceptDataMode>
            <Binding Path="IsInInputMode"/>
    </Views:AddClientView.IsInAcceptDataMode>

   <Grid>
      <Label 
        Height="25" 
        Width="306"
        HorizontalAlignment="Left" 
        Margin="12,12,0,0" 
        OverridesDefaultStyle="False" 
        Style="{DynamicResource CalloutLabel}" 
        VerticalAlignment="Top" Content="Company Name (Name of Organizational Unit)"/>

    <TextBox Height="23" Margin="12,41,12,0" VerticalAlignment="Top" TabIndex="1" />

    <Button 
        Style="{DynamicResource LightButton}" 
        Height="23" Width="75" 
        HorizontalAlignment="Right" 
        VerticalAlignment="Bottom" 
        Margin="0,0,97,12" 
        TabIndex="4">OK</Button>

    <Button 
        Style="{DynamicResource LightButton}" 
        Height="23" Width="75" 
        HorizontalAlignment="Right" 
        VerticalAlignment="Bottom" 
        Margin="0,0,12,12" 
        Command="{Binding Cancel}"
        TabIndex="3">Cancel</Button>

    <CheckBox Content="Make Groups" Height="16" IsChecked="True" FlowDirection="RightToLeft" Margin="150,79,12,0" VerticalAlignment="Top" TabIndex="2" />

    <Rectangle Fill="{DynamicResource HeaderBarFill}" Height="5" Margin="0,0,0,0" Stroke="{x:Null}" VerticalAlignment="Bottom" />
  </Grid>
</UserControl>

      

+1


source







All Articles