Reputation: 4889
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>
Upvotes: 2
Views: 1492
Reputation: 1050
change it to a public property.
private Double _ProfilePhotoSize = 50;
public Double ProfilePhotoSize
{
get { return _ProfilePhotoSize; }
set
{
if (_ProfilePhotoSize != value)
_ProfilePhotoSize = value;
}
}
Upvotes: 2