I'm doing something similar to Multiple Content Presenters in a WPF User control.
I'm creating a visual widget for a conditional if statement, and I want there to be both true and false content. Where it differs from the original post is that I want to be able to have multiple items in the true and false content. Whereas I can bind ContentPresenter's Content property, ItemsPresenter has no similar thing to bind to.
Is there a way around this that I can build into the control (not just have the calling XAML wrap it in a Grid/StackPanel/etc.)?
public class ConditionalBlock : Control
{
static ConditionalBlock ()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ConditionalBlock), new FrameworkPropertyMetadata(typeof(ConditionalBlock)));
}
public ConditionalBlock ()
{
Background = new SolidColorBrush(Color.FromRgb(0x45, 0x0F, 0x45));
}
public static readonly DependencyProperty LeftWidthProperty = DependencyProperty.Register("LeftWidth", typeof(double), typeof(ConditionalBlock), new UIPropertyMetadata(20.0));
public double LeftWidth
{
get => (double) GetValue(LeftWidthProperty);
set => SetValue(LeftWidthProperty, value);
}
public static readonly DependencyProperty BottomHeightProperty = DependencyProperty.Register("BottomHeight", typeof(double), typeof(ConditionalBlock), new UIPropertyMetadata(10.0));
public double BottomHeight
{
get => (double) GetValue(BottomHeightProperty);
set => SetValue(BottomHeightProperty, value);
}
public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(ConditionalBlock), new UIPropertyMetadata("If"));
public string Title
{
get => (string) GetValue(TitleProperty);
set => SetValue(TitleProperty, value);
}
public static readonly DependencyProperty HasSettingsProperty = DependencyProperty.Register("HasSettings", typeof(bool), typeof(ConditionalBlock), new UIPropertyMetadata(true));
public bool HasSettings
{
get => (bool) GetValue(HasSettingsProperty);
set => SetValue(HasSettingsProperty, value);
}
public static readonly DependencyProperty TrueTitleProperty = DependencyProperty.Register("TrueTitle", typeof(string), typeof(ConditionalBlock), new UIPropertyMetadata("True"));
public string TrueTitle
{
get => (string) GetValue(TrueTitleProperty);
set => SetValue(TrueTitleProperty, value);
}
public static readonly DependencyProperty TrueContentProperty = DependencyProperty.Register("TrueContent", typeof(object), typeof(ConditionalBlock), null);
public object TrueContent
{
get => GetValue(TrueContentProperty);
set => SetValue(TrueContentProperty, value);
}
public static readonly DependencyPropertyKey HasTrueItemsProperty = DependencyProperty.RegisterReadOnly("HasTrueItems", typeof(bool), typeof(ConditionalBlock), new UIPropertyMetadata(false));
public bool HasTrueItmes => TrueContent != null;
public static readonly DependencyProperty ElseHeightProperty = DependencyProperty.Register("ElseHeight", typeof(double), typeof(ConditionalBlock), new UIPropertyMetadata(10.0));
public double ElseHeight
{
get => (double) GetValue(ElseHeightProperty);
set => SetValue(ElseHeightProperty, value);
}
public static readonly DependencyProperty FalseTitleProperty = DependencyProperty.Register("FalseTitle", typeof(string), typeof(ConditionalBlock), new UIPropertyMetadata("False"));
public string FalseTitle
{
get => (string) GetValue(FalseTitleProperty);
set => SetValue(FalseTitleProperty, value);
}
public static readonly DependencyProperty FalseContentProperty = DependencyProperty.Register("FalseContent", typeof(object), typeof(ConditionalBlock), null);
public object FalseContent
{
get => GetValue(FalseContentProperty);
set => SetValue(FalseContentProperty, value);
}
public static readonly DependencyPropertyKey HasFalseItemsProperty = DependencyProperty.RegisterReadOnly("HasFalseItems", typeof(bool), typeof(ConditionalBlock), new UIPropertyMetadata(false));
public bool HasFalseItmes => FalseContent != null;
}
<Style TargetType="{x:Type local:ConditionalBlock}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ConditionalBlock}">
<Grid Background="White"
Margin="0,1">
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="3" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!--This is the top bar-->
<Border Grid.Row="0"
Grid.ColumnSpan="3"
CornerRadius="4"
Background="{TemplateBinding Background}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
Margin="7,0,0,0"
VerticalAlignment="Center"
Text="{TemplateBinding Title}"
Foreground="White" />
<Image
Grid.Column="1"
Source="{StaticResource SettingsIcon}"
Visibility="{TemplateBinding HasSettings, Converter={StaticResource BooleanVisibilityConverter}}"
VerticalAlignment="Center"
MaxWidth="10"
Margin="0,1,5,0"
Stretch="Uniform" />
</Grid>
</Border>
<!--This is the true block-->
<Grid
Grid.Row="1"
Grid.Column="0"
Width="{TemplateBinding LeftWidth}"
Visibility="{TemplateBinding HasTrueItems, Converter={StaticResource BooleanVisibilityConverter}}"
Margin="0,-3.5"
Background="{TemplateBinding Background}">
<TextBlock
VerticalAlignment="Center"
Text="{TemplateBinding TrueTitle}"
Foreground="White">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"></RotateTransform>
</TextBlock.LayoutTransform>
</TextBlock>
</Grid>
<Grid
Grid.Row="1"
Grid.Column="1"
Visibility="{TemplateBinding HasTrueItems, Converter={StaticResource BooleanVisibilityConverter}}"
Margin="-1"
Background="{TemplateBinding Background}">
<Border Margin="1,1,-1,1"
CornerRadius="2,0,0,2"
Background="White" />
</Grid>
<Grid
Grid.Row="1"
Grid.Column="2"
Visibility="{TemplateBinding HasTrueItems, Converter={StaticResource BooleanVisibilityConverter}}"
Margin="0,0,0,1">
<ContentPresenter Content="{TemplateBinding TrueContent}" />
</Grid>
<!--This is the else bar-->
<Border Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="3"
Height="{TemplateBinding ElseHeight}"
CornerRadius="4"
Background="{TemplateBinding Background}" />
<!--This is the false block-->
<Grid
Grid.Row="3"
Grid.Column="0"
Width="{TemplateBinding LeftWidth}"
Visibility="{TemplateBinding HasFalseItems, Converter={StaticResource BooleanVisibilityConverter}}"
Margin="0,-3.5"
Background="{TemplateBinding Background}">
<TextBlock VerticalAlignment="Center"
Text="{TemplateBinding FalseTitle}"
Foreground="White">
<TextBlock.LayoutTransform>
<RotateTransform Angle="-90"></RotateTransform>
</TextBlock.LayoutTransform>
</TextBlock>
</Grid>
<Grid
Grid.Row="3"
Grid.Column="1"
Visibility="{TemplateBinding HasFalseItems, Converter={StaticResource BooleanVisibilityConverter}}"
Margin="-1"
Background="{TemplateBinding Background}">
<Border Margin="1,1,-1,1"
CornerRadius="2,0,0,2"
Background="White" />
</Grid>
<Grid
Grid.Row="3"
Grid.Column="2"
Visibility="{TemplateBinding HasFalseItems, Converter={StaticResource BooleanVisibilityConverter}}"
Margin="0,0,0,1">
<ContentPresenter Content="{TemplateBinding FalseContent}" />
</Grid>
<!--This is the bottom bar-->
<Border Grid.Row="4"
Grid.Column="0"
Grid.ColumnSpan="3"
Height="{TemplateBinding BottomHeight}"
CornerRadius="4"
Background="{TemplateBinding Background}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Related
I have a Observable Collection, I want to Filter the collection. The Collection class like a dictionary. I have tried the following code But it is not filtering the collection. I know it is very basic question. I am new to c#. I am studying. Please any one help me to filter the collection. I have mentioned the code below, please refer
GroupModel
public class GroupModel
{
public string Key { get; set; }
public ObservableCollection<ValueModel> Values { get; set; }
}
ValueModel
public class ValueModel
{
public int Id { get; set; }
public string Name { get; set; }
}
ViewModel
Public Class ViewModel
{
public ObservableCollection<GroupModel> MainValues
{
get { return mainValues; }
set { mainValues = value; }
}
public string SearchIndicator
{
get { return searchIndicator; }
set
{
searchIndicator = value;
OnPropertyChanged(SearchIndicator);
ItemsView.Refresh();
}
}
public ViewModel(IMainValueCollection mainValueCollection)
{
MainValue = new ObservableCollection<GroupModel>();
this.MainValue = mainValueCollection;
ItemsView.Filter = new Predicate<object>(o => Filter(o as ValueModel));
}
public ICollectionView ItemsView
{
get
{
var value = (MainValues.SelectMany(a => a.Values)).ToList();
return CollectionViewSource.GetDefaultView((MainValues.SelectMany(a => a.Values)));
}
}
private bool Filter(ValueModel value)
{
if (SearchIndicator == null)
{
return true;
}
return value.Name.IndexOf(SearchIndicator, StringComparison.OrdinalIgnoreCase) != -1;
}
}
MainViewUI
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid
Grid.Row="0"
Height="35"
Margin="5,5,0,5">
<Border
Margin="10,10,10,0"
Padding="1"
BorderBrush="LightGray"
BorderThickness="1"
CornerRadius="0">
<Grid
Height="30"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid
Grid.Row="0"
Grid.Column="0"
Margin="2,0,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Image
Width="25"
Height="25"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Source="/Images/SearchIcon.png" />
</Grid>
<Grid
Name="TextBlockGrid"
Grid.Row="0"
Grid.Column="1"
Height="30"
HorizontalAlignment="Stretch"
VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock
Padding="5,0,0,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Foreground="Gray"
Text="Search">
<TextBlock.Visibility>
<MultiBinding Converter="{StaticResource MultiStringToVisibilityConverter}">
<Binding ElementName="searchBox" Path="Text.IsEmpty" />
<Binding ElementName="searchBox" Path="IsFocused" />
</MultiBinding>
</TextBlock.Visibility>
</TextBlock>
<TextBox
x:Name="searchBox"
Width="{Binding ActualWidth, ElementName=TextBlockGrid}"
Padding="5,0,0,0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
Text="{Binding SearchIndicator, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</Grid>
</Border>
</Grid>
<ItemsControl
Grid.Row="1"
MinWidth="150"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="White"
BorderThickness="0"
ItemsSource="{Binding MainValues, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Expander IsExpanded="True">
<Expander.Header>
<Grid>
<TextBlock x:Name="keys" Text="{Binding Key}" />
</Grid>
</Expander.Header>
<ListBox
Margin="15,0,0,0"
BorderThickness="0"
DisplayMemberPath="Name"
ItemsSource="{Binding Values}" />
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
You are not binding to ItemsView at all.
Replace
ItemsSource="{Binding MainValues, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
with
ItemsSource="{Binding ItemsView}">
Also change the ItemsView implementation to
public ICollectionView ItemsView
{
get { return CollectionViewSource.GetDefaultView(MainValues); }
}
I'm trying to fill my collection with color. I have a border control for displaying the color which is selected using PrepareContainerForItemOverride
method and i have a button control to popup the color in collection. Here is my code.
Picker.cs
public sealed class Picker : ItemsControl
{
private ObservableCollection<SolidColorBrush> _myColors;
public Picker()
{
this.DefaultStyleKey = typeof(Picker);
_myColors = new ObservableCollection<SolidColorBrush>()
{
new SolidColorBrush(Color.FromArgb(255,225,225,25)),
new SolidColorBrush(Color.FromArgb(255,225,25,25)),
new SolidColorBrush(Color.FromArgb(255,225,225,225)),
new SolidColorBrush(Color.FromArgb(255,25,225,25))
};
}
public ObservableCollection<SolidColorBrush> MyColors
{
get
{
return (ObservableCollection<SolidColorBrush>)GetValue(MyColorsProperty);
}
set { SetValue(MyColorsProperty, value); }
}
public static readonly DependencyProperty MyColorsProperty =
DependencyProperty.Register("MyColors",
typeof(ObservableCollection<SolidColorBrush>), typeof(Picker), new
PropertyMetadata(null));
public Popup popup;
protected override void OnApplyTemplate()
{
popup = GetTemplateChild("myPopup") as Popup;
var popupbutton = GetTemplateChild("btn1") as Button;
popupbutton.Click += Popupbutton_Click;
}
private void Popupbutton_Click(object sender, RoutedEventArgs e)
{
popup.IsOpen = popup.IsOpen ? false : true;
}
public bool openPopup
{
get { return (bool)GetValue(openPopupProperty); }
set { SetValue(openPopupProperty, value); }
}
public static readonly DependencyProperty openPopupProperty =
DependencyProperty.Register("openPopup", typeof(bool),
typeof(Picker), new PropertyMetadata(true));
public object Data { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(String propname)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propname));
}
}
}
Generic.xaml
<Style TargetType="local:Picker" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:Picker">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel>
<Border Height="50" BorderBrush="Blue" BorderThickness="5">
<Border.Background>
<SolidColorBrush Color="{Binding Color}" />
</Border.Background>
</Border>
<Popup Name="myPopup" IsOpen="False" IsLightDismissEnabled="True">
<Grid Width="650" Height="300" Background="Red">
<ItemsControl ItemsSource="{TemplateBinding MyColors}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Border BorderThickness="6" BorderBrush="Black">
<Border.Background>
<SolidColorBrush Color="{Binding Color}" />
</Border.Background>
</Border>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Popup>
</StackPanel>
<Button Grid.Column="1" Name="btn1" Height="55" Content="Click me"/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Here, I'm not able to popup the color in collection when the button is clicked and i need to display the selected color in the border contol using PrepareContainerForItemOverride method
The problem is you have bound wrong property to ItemsSource. And private field _myColors you have never used. I have edit your code. It works in my side.
Picker.cs
public Picker()
{
this.DefaultStyleKey = typeof(Picker);
MyColors = new ObservableCollection<SolidColorBrush>()
{
new SolidColorBrush(Color.FromArgb(255,225,225,25)),
new SolidColorBrush(Color.FromArgb(255,225,25,25)),
new SolidColorBrush(Color.FromArgb(255,225,225,225)),
new SolidColorBrush(Color.FromArgb(255,25,225,25))
};
}
public ObservableCollection<SolidColorBrush> MyColors
{
get
{
return (ObservableCollection<SolidColorBrush>)GetValue(MyColorsProperty);
}
set { SetValue(MyColorsProperty, value); }
}
public static readonly DependencyProperty MyColorsProperty =
DependencyProperty.Register("MyColors",
typeof(ObservableCollection<SolidColorBrush>), typeof(Picker), new
PropertyMetadata(null));
Generic.xaml
<Style TargetType="local:Picker" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:Picker">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel>
<Border Height="50" BorderBrush="Blue" BorderThickness="5">
<Border.Background>
<SolidColorBrush Color="{Binding Color}" />
</Border.Background>
</Border>
<Popup Name="myPopup" IsOpen="False" IsLightDismissEnabled="True">
<Grid Width="650" Height="300" >
<ItemsControl ItemsSource="{TemplateBinding MyColors}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Border BorderThickness="15" BorderBrush="{Binding}">
</Border>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Popup>
</StackPanel>
<Button Grid.Column="1" Name="btn1" Height="55" Content="Click me"/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I did a custom button in WPF and I added some properties to use to in style. But some stuff doesn't work correctly
Control.
public class CustomButton : Button
{
public static readonly DependencyProperty TextProperty;
public static readonly DependencyProperty ImageProperty;
public static readonly DependencyProperty ImageRollvoerProperty;
public static readonly DependencyProperty TextMarginProperty;
static CustomButton()
{
TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(CustomButton), new UIPropertyMetadata(null));
ImageProperty = DependencyProperty.Register("Image", typeof(ImageSource), typeof(CustomButton), new UIPropertyMetadata(null));
ImageProperty = DependencyProperty.Register("ImageRollvoer", typeof(ImageSource), typeof(CustomButton), new UIPropertyMetadata(null));
TextMarginProperty = DependencyProperty.Register("TextMargin", typeof(string), typeof(CustomButton), new UIPropertyMetadata(null));
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public ImageSource Image
{
get { return (ImageSource)GetValue(ImageProperty); }
set { SetValue(ImageProperty, value); }
}
public ImageSource ImageImageRollvoer
{
get { return (ImageSource)GetValue(ImageRollvoerProperty); }
set { SetValue(ImageRollvoerProperty, value); }
}
public string TextMargin
{
get { return (string)GetValue(TextMarginProperty); }
set { SetValue(TextMarginProperty, value); }
}
}
Style
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:XposButton}">
<Grid ClipToBounds="True">
<Grid.RowDefinitions>
<RowDefinition Height="{TemplateBinding Height}" />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{TemplateBinding Width}" />
</Grid.ColumnDefinitions>
<local:ClippingBorder Grid.Row="0" Grid.Column="0" BorderThickness="0" CornerRadius="10" Background="{StaticResource OxxoMetroBackground}" BorderBrush="{StaticResource OxxoMetroBorder}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<local:ClippingBorder Background="{StaticResource OxxoMetroBackground}" BorderBrush="{StaticResource BorderBrush}" BorderThickness="2" CornerRadius="9">
<local:ClippingBorder x:Name="Overlay" ClipToBounds="True" Background="Transparent" BorderBrush="{StaticResource OxxoMetroBorder}" BorderThickness="0">
<Image Name="btnImage" Source="{TemplateBinding Image}" Style="{StaticResource ImageUninhabitable}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" />
</local:ClippingBorder>
</local:ClippingBorder>
</local:ClippingBorder>
<TextBlock Grid.Row="1" Grid.Column="0" HorizontalAlignment="Center" Margin="{TemplateBinding TextMargin}" Text="{TemplateBinding Text}" Style="{DynamicResource TextBlockMenuImg}" FontFamily="{TemplateBinding FontFamily}" FontSize="{TemplateBinding FontSize}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
View
<ctrl:CustomButton FontFamily="Roboto" Margin="17" TextMargin="0,20,0,0" Width="150" Image="{Binding Path=ImageUrl}" Text="{Binding ShowName}" x:Name="btnMenu" Style="{StaticResource CustomButtonStyle}" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path= DataContext.SelectMenuCommand}" CommandParameter="{Binding}" />
The Image, and text are correctly displayed, the FontFamily, and TextMargin doesn't work correctly.
The binding on Margin probably isn't working because the property should be defined as a Thickness type rather than String.
public Thickness TextMargin
I have been experimenting with WPF and using a CustomControl have made my own panel type so I can make all my panels look like a box with backgrounds, rounded corners etc.
The trouble I am not having is I want to change the property of an item at runtime that is bound using TemplateBinding.
My issue is changing this through code is not working.
Was hoping someone could spot my error and tell me where I am being slightly dense.
This finds the contentControl and changes the value, this just never appears in the application, as if the binding is not active.
Hope someone can help.
The control Template.
<ControlTemplate x:Key="ContentBoxControlTemplate" TargetType="{x:Type local:ContentBox}"><Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.124*"/>
<RowDefinition Height="0.876*"/>
</Grid.RowDefinitions>
<Border BorderBrush="Black" BorderThickness="0" HorizontalAlignment="Stretch" Height="Auto" VerticalAlignment="Stretch" CornerRadius="20" Grid.RowSpan="2" Style="{TemplateBinding Style}" />
<Rectangle HorizontalAlignment="Stretch" Height="Auto" RadiusY="0" StrokeThickness="0" VerticalAlignment="Stretch" Width="Auto" Margin="10,0,10,20" Fill="White" Grid.Row="1"/>
<Rectangle Fill="{DynamicResource TopInnerShadow}" HorizontalAlignment="Stretch" Height="Auto" RadiusY="0" StrokeThickness="0" VerticalAlignment="Stretch" Width="Auto" Margin="10,0,10,20" Grid.Row="1"/>
<Rectangle Fill="{DynamicResource RightInnerShadow}" HorizontalAlignment="Stretch" Height="Auto" RadiusY="0" StrokeThickness="0" VerticalAlignment="Stretch" Width="Auto" Margin="10,0,10,20" Grid.Row="1"/>
<TextBlock Grid.Row="0" x:Name="txtBoxHeading" HorizontalAlignment="Stretch" TextWrapping="Wrap" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Title}" VerticalAlignment="Stretch" d:LayoutOverrides="Width, Height" Foreground="White" FontSize="36" FontFamily="Arial" Margin="20,5"/>
<Grid Grid.Row="1">
<ContentControl Content="{TemplateBinding Content}" Margin="10,0,10,20"/>
</Grid>
</Grid>
</ControlTemplate>
The ContentControl
public class ContentBox : ContentControl
{
static ContentBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ContentBox), new FrameworkPropertyMetadata(typeof(ContentBox)));
}
private string _title = "";
public string Title
{
get { return _title; }
set { _title = value; }
}
// Dependency Property
public static DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(ContentBox), new FrameworkPropertyMetadata("Title"));
}
The xaml for using the content control
And finally the code to change the property
(this.Parent as ContentBox).Title = "Campaign: " + campaigns[0].Name;
I found my mistake, and I was as I thought, being silly!!
In the ContentControl I was not setting the dependancy property properly.
Changing the property in the contentcontrol to the following fixed my problem
public string Title
{
get { return (string)this.GetValue(TitleProperty); }
set { this.SetValue(TitleProperty, value); }
}
I created the following xaml:
<Button x:Name="PriceButton">
<Button.Template>
<ControlTemplate>
<Border x:Name="ButtonBorder"
CornerRadius="2"
Background="{StaticResource DarkReflectionBrush}"
BorderBrush="Black"
BorderThickness="1" HorizontalAlignment="Stretch">
<ContentPresenter
VerticalAlignment="Center"
HorizontalAlignment="Left">
<ContentPresenter.Content>
<Grid x:Name="ContentGrid" HorizontalAlignment="Left" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="15*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="15*" />
</Grid.ColumnDefinitions>
<TextBlock x:Name="Price" Grid.Column="0" FontFamily="Calibri" FontSize="8"
VerticalAlignment="Bottom" Text="{Binding Path=PriceText}"
Foreground="{Binding Path=PriceColor}" ></TextBlock>
<TextBlock x:Name="Main" Grid.Column="1" FontFamily="Calibri" FontSize="14"
Text="{Binding Path=MainText}"
Foreground="{Binding Path=MainTextColor}" />
<TextBlock x:Name="Vol" Grid.Column="2" FontFamily="Calibri" FontSize="8"
VerticalAlignment="Bottom" Text="{Binding Path=VolatilityText}"
Foreground="{Binding Path=VolatilityColor}" />
</Grid>
</ContentPresenter.Content>
</ContentPresenter>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Button.IsPressed" Value="true">
<Setter TargetName="ButtonBorder" Property="Background" Value="{StaticResource PressedBrush}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="0.5" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
Here's the Code Behind:
public static readonly DependencyProperty PriceTextProperty =
DependencyProperty.Register(
"PriceText",
typeof (string),
typeof (LivePriceVolButton),
new FrameworkPropertyMetadata(string.Empty, OnPriceTextChanged));
public string PriceText {
get {
return (string)GetValue(PriceTextProperty);
}
set {
SetValue(PriceTextProperty, value);
}
}
public static readonly DependencyProperty PriceColorProperty =
DependencyProperty.Register(
"PriceColor",
typeof (Color),
typeof (LivePriceVolButton),
new FrameworkPropertyMetadata(Colors.White));
public Color PriceColor {
get {
return (Color) GetValue(PriceColorProperty);
}
set {
SetValue(PriceColorProperty, value);
}
}
public static readonly DependencyProperty MainTextProperty =
DependencyProperty.Register(
"MainText",
typeof (string),
typeof (LivePriceVolButton),
new FrameworkPropertyMetadata(string.Empty));
public string MainText {
get {
return (string) GetValue(MainTextProperty);
}
set {
SetValue(MainTextProperty, value);
}
}
public static readonly DependencyProperty MainTextColorProperty =
DependencyProperty.Register(
"MainTextColor",
typeof(Color),
typeof(LivePriceVolButton),
new FrameworkPropertyMetadata(Colors.White));
public Color MainTextColor {
get {
return (Color) GetValue(MainTextColorProperty);
}
set {
SetValue(MainTextColorProperty, value);
}
}
public static readonly DependencyProperty VolatilityTextProperty =
DependencyProperty.Register(
"VolatilityText",
typeof(string),
typeof(LivePriceVolButton),
new FrameworkPropertyMetadata(string.Empty));
public string VolatilityText {
get {
return (string) GetValue(VolatilityTextProperty);
}
set {
SetValue(VolatilityTextProperty, value);
}
}
public static readonly DependencyProperty VolatilityColorProperty =
DependencyProperty.Register(
"VolatilityColor",
typeof(Color),
typeof(LivePriceVolButton),
new FrameworkPropertyMetadata(Colors.White));
public Color VolatilityColor {
get {
return (Color) GetValue(VolatilityColorProperty);
}
set {
SetValue(VolatilityColorProperty, value);
}
}
When I insert my user control onto a form like this
<my:LivePriceVolButton Margin="43.03,0,0,32" x:Name="livePriceVolButton1"
xmlns:my="clr-namespace:MultiTextBlockButton" HorizontalAlignment="Left"
Width="91.703" Height="30" VerticalAlignment="Bottom"
MainText="MID" MainTextColor="LightBlue" PriceColor="Red" PriceText="1234.56"
VolatilityText="12.2%" VolatilityColor="Aqua" />
I don't see anything in the button at all. Any ideas?
Thanks
You have to set the DataContext for the Button to be equal to the parent UserControl for your Bindings to work. Try something like this:
<UserControl x:Name="uc" ...>
<Button x:Name="PriceButton" DataContext="{Binding ElementName=uc}">
<!--Other code here...-->
</Button>
</UserControl>
I also see that you're using "Color" as the Type for some of your DependencyProperties. I suggest you change them to "Brush" instead. Otherwise the related bindings (e.g. Foreground="{Binding VolatilityColor}") won't work.