visc
visc

Reputation: 4959

UWP UserControl + ContentControl

I'm trying to understand how content controls work and how I can place one inside a user control I'm constructing. From what I understand, my user control should have an object dependency property and then I should be able to add a content control to my user control and bind it to the dependency property.

I've tried variations of the User Control XAML, including bypassing the ScrollViewer element and placing the ContentControl inside the base grid of the User Control XAML.

How do I place this image inside this control? And more broadly how do I place any XAML inside a User Control?

User Control CS

namespace CoreProject.UserControls
{
public sealed partial class ZoomControl : UserControl
{
    public ZoomControl()
    {
        this.InitializeComponent();
    }

    #region Properties
    public static readonly DependencyProperty ZoomContentProperty =
    DependencyProperty.Register("ZoomContent", typeof(object), typeof(ZoomControl), new PropertyMetadata(null));
    public object ZoomContent
    {
        get { return (object)GetValue(ZoomContentProperty); }
        set { SetValue(ZoomContentProperty, value); }
    }
    #endregion

    public void UnZoom()
    {
        // unzoom
        ImageScrollViewer.Visibility = Visibility.Visible;
        var period = TimeSpan.FromMilliseconds(10);
        Windows.System.Threading.ThreadPoolTimer.CreateTimer(async (source) =>
        {
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                ImageScrollViewer.ChangeView(0.0, 0.0, 0.8F, true);
                ImageScrollViewer.Visibility = Visibility.Collapsed;
            });
        }, period);
    }

    public void ZoomToPosition(double zoomOriginX, double zoomOriginY, float zoomFactor, bool disableAnimations)
    {
        ImageScrollViewer.Visibility = Visibility.Visible;
        var period = TimeSpan.FromMilliseconds(10);
        Windows.System.Threading.ThreadPoolTimer.CreateTimer(async (source) =>
        {
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                ImageScrollViewer.ChangeView(zoomOriginX, zoomOriginY, 1.2F, disableAnimations);
            });
        }, period);
    }
}

}

User Control Xaml

<Grid>
    <ScrollViewer x:Name="ImageScrollViewer" 
                  ZoomMode="Enabled" 
                  Visibility="Collapsed" 
                  HorizontalContentAlignment="Center" 
                  VerticalContentAlignment="Center" 
                  Background="Transparent" 
                  HorizontalScrollMode="Enabled"
                  VerticalScrollMode="Enabled"
                  HorizontalScrollBarVisibility="Hidden"
                  VerticalScrollBarVisibility="Hidden">
        <Grid>
            <!-- HERE IS WHERE I WANT TO PLACE MY CONTENT -->
            <ContentControl Content="{Binding ZoomContent, ElementName=zoomContent}" />
        </Grid>
    </ScrollViewer>
</Grid>

User Control Usage

<usercontrols:ZoomControl x:Name="ZoomControl">
    <usercontrols:ZoomControl.ZoomContent>
        <!-- THIS IS HOW I WANT TO ADD MY CONTENT, SIMPLY PLACE XAML ELEMENT -->
        <Image Source="/Assets/colocationDataCenterData.jpg" />
    </usercontrols:ZoomControl.ZoomContent>
</usercontrols:ZoomControl>

Upvotes: 2

Views: 3210

Answers (1)

Johnny Westlake
Johnny Westlake

Reputation: 1459

 <Grid>
     <!-- HERE IS WHERE I WANT TO PLACE MY CONTENT -->
     <ContentControl Content="{x:Bind ZoomContent, Mode=OneWay}" />
 </Grid>

You can also use x:Bind instead - it takes the Binding context as the class itself (your UserControl), so you can straight bind.

If you want classical binding to work you need to name and userControl INSIDE the usercontrol itself. (BTW, typically you'd do this as a TEMPLATED control instead and use templatebindings)

<UserControl x:Name="zoomContent">
    <Grid>
         <ScrollViewer x:Name="ImageScrollViewer" 
              ZoomMode="Enabled" 
              Visibility="Collapsed" 
              HorizontalContentAlignment="Center" 
              VerticalContentAlignment="Center" 
              Background="Transparent" 
              HorizontalScrollMode="Enabled"
              VerticalScrollMode="Enabled"
              HorizontalScrollBarVisibility="Hidden"
              VerticalScrollBarVisibility="Hidden">
         <Grid>
             <!-- HERE IS WHERE I WANT TO PLACE MY CONTENT -->
             <ContentControl Content="{Binding ZoomContent, ElementName=zoomContent}" />
         </Grid>
     </ScrollViewer>
  </Grid>
</UserControl>

Upvotes: 3

Related Questions