c# - Custom Control, bind to code behind


Question: 

Having trouble binding to the data in my code behind for my custom control. Obviously I have got to use the Generic.xaml to style my control, and I want to bind to the data in my control UserProfile.cs.

This is the code behind:

using System;
using System.Windows;
using System.Windows.Controls;

namespace Controls
{
    public class UserProfile : Control
    {
        static UserProfile()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(UserProfile), 
                new FrameworkPropertyMetadata(typeof(UserProfile)));
        }

        private Double _ProfilePhotoSize = 50;
        private Double ProfilePhotoSize
        {
            get { return _ProfilePhotoSize; }
            set
            {
                if (_ProfilePhotoSize != value)
                    _ProfilePhotoSize = value;
            }
        }
    }
}

And here is the XAML with the binding, removed the last part as it isn't needed:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Controls">

    <Style TargetType="{x:Type local:NumericUpDown}">
        <Style.Resources>
            <SolidColorBrush x:Key="colour1" Color="#434953" />
            <SolidColorBrush x:Key="colour2" Color="#22252b" />
            <SolidColorBrush x:Key="colour3" Color="#606876" />
        </Style.Resources>

        <Setter Property="Width" Value="85" />
        <Setter Property="Margin" Value="5" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:NumericUpDown}">
                    <Border Focusable="{TemplateBinding Focusable}"
                            Width="{TemplateBinding Width}"
                            x:Name="Border">
                        <Grid Focusable="False">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="auto"/>
                                <ColumnDefinition Width="1*"/>
                                <ColumnDefinition Width="auto"/>
                            </Grid.ColumnDefinitions>

                            <Button x:Name="PART_DecreaseButton" 
                                    Grid.Column="0">
                                <Button.Content>
                                    <Path Data="M0,0 L1,0 0.5,1Z"
                                          Fill="White"
                                          Width="8"
                                          Height="6"
                                          Stretch="Fill"/>
                                </Button.Content>
                                <Button.Template>
                                    <ControlTemplate TargetType="Button">
                                        <Border Name="Border"
                                                Background="{DynamicResource colour1}" 
                                                Width="25" 
                                                Height="25"
                                                CornerRadius="5 0 0 5">
                                            <ContentPresenter />
                                        </Border>
                                        <ControlTemplate.Triggers>
                                            <Trigger Property="IsMouseOver" Value="True">
                                                <Setter TargetName="Border" Property="Background" Value="{DynamicResource colour3}" />
                                            </Trigger>
                                        </ControlTemplate.Triggers>
                                    </ControlTemplate>
                                </Button.Template>
                            </Button>

                            <TextBox x:Name="PART_TextBox"
                                     Grid.Column="1"
                                     Foreground="White"
                                     Background="{DynamicResource colour2}"
                                     VerticalContentAlignment="Center"
                                     HorizontalContentAlignment="Center"
                                     HorizontalAlignment="Stretch" 
                                     BorderThickness="0"
                                     Focusable="False" Text="0" />

                            <Button x:Name="PART_IncreaseButton" 
                                    Grid.Column="2">
                                <Button.Content>
                                    <Path Data="M0,1 L1,1 0.5,0Z" 
                                          Width="8"
                                          Height="6"
                                          Fill="White" 
                                          Stretch="Fill" />
                                </Button.Content>
                                <Button.Template>
                                    <ControlTemplate TargetType="Button">
                                        <Border Name="Border" 
                                                Background="{DynamicResource colour1}" 
                                                Width="25" 
                                                Height="25"
                                                CornerRadius="0 5 5 0">
                                            <ContentPresenter />
                                        </Border>
                                        <ControlTemplate.Triggers>
                                            <Trigger Property="IsMouseOver" Value="True">
                                                <Setter TargetName="Border" Property="Background" Value="{DynamicResource colour3}" />
                                            </Trigger>
                                        </ControlTemplate.Triggers>
                                    </ControlTemplate>
                                </Button.Template>
                            </Button>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Style TargetType="{x:Type local:UserProfile}">
        <Setter Property="DataContext" Value="{x:Type local:UserProfile}" />
        <Setter Property="Foreground" Value="White" />
        <Setter Property="FontSize" Value="16" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:UserProfile}">
                    <Grid x:Name="circleGrid" Width="{Binding Path=ProfilePhotoSize, RelativeSource={RelativeSource AncestorType={x:Type local:UserProfile}}}">
...

This is the binding error i'm getting:

BindingExpression path error: 'ProfilePhotoSize' property not found on 'object' ''UserProfile' (Name='')'. BindingExpression:Path=ProfilePhotoSize; DataItem='UserProfile' (Name=''); target element is 'Grid' (Name='circleGrid'); target property is 'Width' (type 'Double')

Edit: Just moved some code around and getting issue with the code now, I want to the border size to adjust based on the size the user makes the control, so I have made a new class and property which gets the ProfilePhotoSize and then will divide it by a number.

Code Behind

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;

namespace Controls
{
    public class UserProfile : Control
    {
        static UserProfile()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(UserProfile),
                new FrameworkPropertyMetadata(typeof(UserProfile)));
        }
    }
    public class UserProfileData : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }

        private Double _ProfilePhotoSize = 50;
        public Double ProfilePhotoSize
        {
            get { return _ProfilePhotoSize; }
            set
            {
                if (_ProfilePhotoSize != value)
                    _ProfilePhotoSize = value;
                OnPropertyChanged("ProfilePhotoSize");
            }
        }
        private Double _ProfileBorderThickness = 3;
        public Double ProfileBorderThickness
        {
            get { return _ProfileBorderThickness; }
            set
            {
                double x = ProfilePhotoSize / 3;
                if (_ProfileBorderThickness != x)
                    _ProfileBorderThickness = x;
                OnPropertyChanged("ProfileBorderThickness");
            }
        }
    }
}

This is the XAML, binding no longer works :S

XAML

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Controls">

    <Style TargetType="{x:Type local:UserProfile}">
        <Setter Property="DataContext" Value="{x:Type local:UserProfile}" />
        <Setter Property="Foreground" Value="White" />
        <Setter Property="FontSize" Value="16" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:UserProfile}">
                    <Grid x:Name="circleGrid" Width="{Binding ProfilePhotoSize, RelativeSource={RelativeSource AncestorType={x:Type local:UserProfileData}}}">
                        <Grid.RowDefinitions>



1 Answer: 

change it to a public property.

    private Double _ProfilePhotoSize = 50;
    public Double ProfilePhotoSize
    {
        get { return _ProfilePhotoSize; }
        set
        {
            if (_ProfilePhotoSize != value)
                _ProfilePhotoSize = value;
        }
    }
 

More Articles


wpf - Canvas control is not available in Windows form application?

WPF Canvas control is not available in Windows form application. Am using Visual Studio 2010. Framework 4.0. Is there way to add these controls to VS2010 toolbox?

material design - android lollipop toolbar: how to hide/show the toolbar while scrolling?

I'm using the new toolbar widget introduced in the appcompat / support-v7. I would like to hide/show the toolbar depending on if the user is scrolling up/down the page, just like in the new Google's playstore app or NewsStand app. Is there something built into the toolbar widget for this or should I

Android: pin TabLayout to top of Scrollview

I was looking at the twitter app on my phone.You can see that when a user scrolls up, the tabLayout actually just pins itself onto the bottom of the toolbar nicely and does not move at all.I thought maybe they did it by just putting all of the top part of the app (the profile picture, the profile wa


WPF Frame Source Refreshing the Loaded Page

I've come across a strange scenario where a frame refuses to refresh its content.I can kinda understand what's happening but the solution is not coming to me.I have a page that has a frame (Frame1) and several buttons. When I click on a button a page is loaded into the frame. This works perfectly in

android - Horizontal and Vertical linear layout inside a scroll view

I am trying to get a combination of Views established. They must constantly have a Button and Edittext box at the top horizontally next to each other and below that a vertical list of Textviews. The vertical list should be enclosed in a ScrollView to allow the user to scroll down through the TextVie

PhpStorm: automatically rename file on remote host when renaming it locally

Is there any configuration in PhpStorm that automatically renames file on remote host when you rename it locally and reverse?


xamarin.forms - Margin to a Image in Xamarin Forms

I have an image on my Xamarin.Forms. I want to add some margin from Top. Form.XAML:-<ContentPage.Content> <Grid> <Image x:Name="image" /> </Grid></ContentPage.Content>"Form.XAML.cs:- image.Source = ImageSource.FromFile (Height > Width ? "portrait.jpg"

c# - ASP.NET Chart Control and Databinding to multiple Series

I am working with the ASP.NET chart control and I am using the following code to databind data to the chart control. The chart has three series on it: Series1, Series2 and Series3. The problem that I am having with the code below is that it only seems to bind to the first series so that when the ch

How to disable version control in phpstorm?

I am playing around with phpstorm and somehow I activated version control. I don't need it. Now all my tabs are different: orange text on gray background. All files in the file view are orange. How do I disable version control?

Keras autoencoder outputting wrong shape

I'm trying to build a deep convolutional autoencoder in Keras, but it keeps outputting the wrong shape.Code: def build_network(input_shape): input_input = Input(shape=input_shape) #Encode x = Conv2D(16, (3, 3), activation='relu', padding = 'same')(input_input) x = MaxPooling2D((2, 2), p