Binding to a userControl which contains custom control - c#

I want to use the ToggleSwitch control of the WPF Spark project
So I created a UserControl which contains a ToggleSwitch control and configures it (color, size, etc).
<UserControl x:Class="WpfControls.ToggleSwitch.MyToggleSwitchControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:toggleSwitch="clr-namespace:WpfControls.ToggleSwitch"
d:DesignHeight="300"
d:DesignWidth="300"
mc:Ignorable="d">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/WpfControls;component/ToggleSwitch/ToggleSwitch.Generic.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<toggleSwitch:ToggleSwitch x:Name="Toggle"
Width="54"
Height="21"
Margin="0"
Background="Black"
BorderThickness="2"
CheckedForeground="White"
CheckedText="Yes"
CheckedToolTip=""
CornerRadius="10"
FontFamily="Tahoma"
FontSize="10"
FontWeight="Normal"
IsCheckedLeft="False"
Padding="0"
ThumbBorderThickness="2"
ThumbCornerRadius="21"
ThumbGlowColor="Gray"
ThumbShineCornerRadius="20,20,0,0"
ThumbWidth="35"
UncheckedForeground="Black"
UncheckedText="No"
UncheckedToolTip="No">
</toggleSwitch:ToggleSwitch>
</Grid>
</UserControl>
The ToggleSwitch is a CustomControl which overrides the standard WPF ToggleButton.
Now I want to use the ToggleButton property IsChecked in my XAML for Binding.
<toggleSwitch:MyToggleSwitchControl IsChecked="{Binding IsChecked}" />
How can I achieve that?

Create in code-behind DependencyProperty:
public bool IsToggleChecked
{
get { return (bool)GetValue(IsToggleCheckedProperty); }
set { SetValue(IsToggleCheckedProperty, value); }
}
public static readonly DependencyProperty IsToggleCheckedProperty =
DependencyProperty.Register("IsToggleChecked", typeof(bool), typeof(MyToggleSwitchControl), new PropertyMetadata(false));
and bind it to IsChecked property of your ToggleSwitch:
<toggleSwitch:ToggleSwitch IsChecked="{Binding RelativeSource={RelativeSource AncestorLevel=1,AncestorType=UserControl,Mode=FindAncestor}, Path=IsToggleChecked}"
After doing this you'll be able to do:
<toggleSwitch:MyToggleSwitchControl IsToggleChecked="{Binding IsChecked}" />

You could use an dependency property.
In your custom control add a dependency property like this:
public static readonly DependencyProperty IsCheckedProperty =
DependencyProperty.Register("IsChecked", typeof(bool),
typeof(MyToggleSwitchControl), null);
// .NET Property wrapper
public bool IsChecked
{
get
{
return (bool)GetValue(IsCheckedProperty);
}
set { SetValue(IsCheckedProperty, value); }
}

Related

Updating custom control

I have custom ComboBox control which allows to pick colors, like described in this article Color Picker using WPF Combobox.
I insert custom ComboBox in MainWindow this way:
<local:Colorpicker x:Name="brushesComboBox"></local:Colorpicker>
When I select colors manually, it works fine, but if I set the color programmatically like that:
brushesComboBox.SelectedColor= new SolidColorBrush(Colors.Aquamarine);
ComboBox doesn`t update itself.
I understand that I will need to modify the code of Colorpicker class, so that when dependancy property is set it will force to update selected index in the internal combobox. How do I do that?
Colorpicker class, xaml part:
<UserControl x:Class="WpfParabola.Colorpicker"
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:local="clr-namespace:WpfParabola"
xmlns:sys="clr-namespace:System;assembly=mscorlib" Name="uccolorpicker"
mc:Ignorable="d"
d:DesignHeight="20" d:DesignWidth="200">
<UserControl.Resources>
<ResourceDictionary>
<ObjectDataProvider MethodName="GetType"
ObjectType="{x:Type sys:Type}" x:Key="colorsTypeOdp">
<ObjectDataProvider.MethodParameters>
<sys:String>System.Windows.Media.Colors, PresentationCore,
Version=3.0.0.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35</sys:String>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ObjectDataProvider ObjectInstance="{StaticResource colorsTypeOdp}"
MethodName="GetProperties" x:Key="colorPropertiesOdp">
</ObjectDataProvider>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<ComboBox Name="superCombo"
ItemsSource="{Binding Source={StaticResource colorPropertiesOdp}}"
SelectedValuePath="Name"
SelectedValue="{Binding ElementName=uccolorpicker,
Path=SelectedColor}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Width="50" Height="{Binding ElementName=FontSize+4}" Margin="2" Background="{Binding Name}"/>
<TextBlock TextAlignment="Left" VerticalAlignment="Center" Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
</UserControl>
Colorpicker class, code behind:
public partial class Colorpicker : UserControl
{
public Colorpicker()
{
InitializeComponent();
superCombo.SelectedIndex = 0;
}
public Brush SelectedColor
{
get { return (Brush)GetValue(SelectedColorProperty); }
set{SetValue(SelectedColorProperty, value);}
}
// Using a DependencyProperty as the backing store for SelectedColor. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SelectedColorProperty =
DependencyProperty.Register("SelectedColor", typeof(Brush), typeof(Colorpicker), new UIPropertyMetadata(null));
}
You can add callback to your dependency property and find the index based on the new Brush value. You can modify your SelectedColorProperty initialization below.
public static readonly DependencyProperty SelectedColorProperty = DependencyProperty.Register("SelectedColor", typeof(Brush), typeof(Colorpicker), new PropertyMetadata(default(Brush), OnSelectedColorChanged));
private static void OnSelectedColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var newBrush = (Brush)e.NewValue;
var colorPicker = (Colorpicker)d;
var comboBox = colorPicker.superCombo;
// Find your index here using the new Brush value.
// And update the selected index of your ComboBox.
}

Get property value WPF

I am trying get a value from a property but isn't working I always get a null value.
string imageNormal;
public static readonly DependencyProperty ImageNormalProperty =
DependencyProperty.Register("ImageNormal", typeof(string), typeof(MainWindow));
public string ImageNormal
{
get { return (string)GetValue(ImageNormalProperty); }
set { SetValue(ImageNormalProperty, value); }
}
public ButtonImageStyle()
{
InitializeComponent();
DataContext = this;
Console.WriteLine("Path: " + ImageNormal);
}
Xaml ButtonImageStyle.xaml:
<Image Source="{Binding ImageNormal}" Stretch="None" HorizontalAlignment="Center" VerticalAlignment="Center" />
Xaml MainWindow.xaml:
<local:ButtonImageStyle HorizontalAlignment="Left" Height="60" VerticalAlignment="Top" Width="88" ImageNormal="C:/Users/Xafi/Desktop/add.png"/>
I always obtain next output:
Path:
since your ImageSource is have to be binded to it's parent DependencyProperty (which is defined to your code behind), you have to define your binding to be rlative to your UserControl (let's name it This). Thus please try to change your xaml in the next way:
Xaml code
<UserControl x:Class="SomeBindingExampleSOHelpAttempt.ButtonImageStyle"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" x:Name="This">
<Grid>
<Image Source="{Binding ElementName=This, Path=ImageNormal, UpdateSourceTrigger=PropertyChanged}"
Stretch="None" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid></UserControl>
Here you can find an additional perfect answer.
Regards.

how to Hide buttons in usercontrol from main window?

I have a user control that have a multi buttons and In the application i use this user control on multi windows ,but i want to Collapsed (shown/hidden) some buttons if the user select in the application a window 1 and show same button if the user select in the application a window 2
UserControl
<Grid x:Name="girdBtuWidow" >
<StackPanel Orientation="Horizontal">
<Button Content="add" x:Name="add" Visibility="{Binding window1_Loaded}" x:FieldModifier="public" Height="50" Width="100" Margin="0" Click="add_click" />
<Button Content="show history" x:Name="Personal" Height="50" Width="100" Margin="0" />
<Button Content="Show Customer" x:Name="Customer" Height="50" Width="100" Margin="0" />
</StackPanel>
</Grid>
how to set the property (Visibility) of button in the User Control from the application window ?
You don't need to use a Window_Loaded Event here.
You need to expose a Visibility property for each of your buttons in your UserControls.
In your UserControl add a binding to each button for the Visibility property:
Visibility="{Binding AddButtonVisibility}"
Visibility="{Binding ShowHistoryButtonVisibility}"
Visibility="{Binding ShowCustomerButtonVisibility}"
Make sure you add a DataContext to your UserControl, I generally use Self:
DataContext="{Binding RelativeSource={RelativeSource Self}}"
In your UserControl Code Behind add Dependency Properties for each of the Bindings above:
public Visibility AddButtonVisibility
{
get { return (Visibility)GetValue(AddButtonVisibilityProperty); }
set { SetValue(AddButtonVisibilityProperty, value); }
}
// Using a DependencyProperty as the backing store for AddButtonVisibility. This enables animation, styling, binding, etc...
public static readonly DependencyProperty AddButtonVisibilityProperty =
DependencyProperty.Register("AddButtonVisibility", typeof(Visibility), typeof(UserControl1), new PropertyMetadata(Visibility.Visible));
public Visibility ShowHistoryButtonVisibility
{
get { return (Visibility)GetValue(ShowHistoryButtonVisibilityProperty); }
set { SetValue(ShowHistoryButtonVisibilityProperty, value); }
}
// Using a DependencyProperty as the backing store for ShowHistoryButtonVisibility. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ShowHistoryButtonVisibilityProperty =
DependencyProperty.Register("ShowHistoryButtonVisibility", typeof(Visibility), typeof(UserControl1), new PropertyMetadata(Visibility.Visible));
public Visibility ShowCustomerButtonVisibility
{
get { return (Visibility)GetValue(ShowCustomerButtonVisibilityProperty); }
set { SetValue(ShowCustomerButtonVisibilityProperty, value); }
}
// Using a DependencyProperty as the backing store for ShowCustomerButtonVisibility. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ShowCustomerButtonVisibilityProperty =
DependencyProperty.Register("ShowCustomerButtonVisibility", typeof(Visibility), typeof(UserControl1), new PropertyMetadata(Visibility.Visible));
In Visual Studio, There is a code snippet shortcut for Dependency Properties - type propdp and hit tab twice.
Now, to use the properties you have just created put the Usercontrol onto the relevant window:
<local:UserControl1 AddButtonVisibility="Collapsed" />
local is the project namespaces' alias - defined at the top of your Window. You can just drag and drop the UserControl onto your window, and it will do this for you. (You may need to rebuild in order to see your UserControls in your Toolbox.
You should now see your control with the Add Button collapsed.
For completeness sake, here is the XAML side of things:
UserControl Xaml:
<UserControl x:Class="WpfApplication2.UserControl1"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid x:Name="girdBtuWidow" >
<StackPanel Orientation="Horizontal">
<Button Content="Add" x:Name="add" Height="50" Width="100" Margin="0" Click="Add_Click" Visibility="{Binding AddButtonVisibility}"/>
<Button Content="Show History" x:Name="Personal" Height="50" Width="100" Margin="0" Click="ShowHistory_Click" Visibility="{Binding ShowHistoryButtonVisibility}" />
<Button Content="Show Customer" x:Name="Customer" Height="50" Width="100" Margin="0" Click="ShowCustomer_Click" Visibility="{Binding ShowCustomerButtonVisibility}"/>
</StackPanel>
</Grid>
Window1.Xaml:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication2" x:Class="WpfApplication2.Window1"
Title="Window1" Height="300" Width="308">
<Grid>
<local:UserControl1 HorizontalAlignment="Left" VerticalAlignment="Top" AddButtonVisibility="Collapsed" />
</Grid>
public static readonly DependencyProperty onBackVisibilityProperty =
DependencyProperty.Register("onBackVisibility", typeof(Visibility), typeof(MyToolBar), new PropertyMetadata(Visibility.Visible));
public Visibility onBackVisibility
{
get { return (Visibility)GetValue(onBackVisibilityProperty); }
set { SetValue(onBackVisibilityProperty, value); }
}
public static readonly DependencyProperty onBackVisibilityProperty =
DependencyProperty.Register("onBackVisibility", typeof(Visibility), typeof(MyToolBar), new PropertyMetadata(Visibility.Visible));
public Visibility onBackVisibility
{
get { return (Visibility)GetValue(onBackVisibilityProperty); }
set { SetValue(onBackVisibilityProperty, value); }
}
//After this goto xaml
Button Name="tbrBack"
ToolTip="{DynamicResource Back}"
VerticalAlignment="Center"
VerticalContentAlignment="Center"
Click="tbrBack_Click"
Visibility="{Binding onBackVisibility ,ElementName = usercontrol}

IValueConverter doesn't execute

I have this XAML Code (ErdMenuItem.xaml):
<UserControl x:Class="ErdBuilder.ErdMenuItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:erdBuilder="clr-namespace:ErdBuilder"
x:Name="UserControl">
<UserControl.Resources>
<erdBuilder:ByteImageConverter x:Key="imageConverter" />
</UserControl.Resources>
<Image Source="{Binding Converter={StaticResource imageConverter}, ElementName=UserControl, Path=Icon}" />
</UserControl>
If I write:
<Image Source="{Binding Converter={StaticResource imageConverter}, ElementName=UserControl, Path=Icon}" />
Then the Converter will not be executed - I use Breakpoints in the Converter. But if I use this:
<Image Source="{Binding Converter={StaticResource imageConverter}}" />
Then the Converter will be executed. Icon is a Dependency Property of type string. I dont know why the Converter will not be executed as far as I add the DependencyProperty which should bring in the Value which I want to convert. Any Ideas ?
The Icon is here (ErdMenuItem.xaml.cs):
namespace ErdBuilder
{
public partial class ErdMenuItem
{
public static readonly DependencyProperty IconProperty = DependencyProperty.Register("Icon", typeof(string), typeof(ErdMenuItem), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure));
public string Icon
{
get { return (string)GetValue(IconProperty); }
set { SetValue(IconProperty, value); }
}
}
}
That's because there's no data in DataContext. The binding expression returns value of the current DataContext. You can set DataContext for Image by using {Binding Converter={StaticResource imageConverter}, Path=Icon} expression or set it for the root element (UserControl in your case). This option is better, as you can use RelativeSource expression to avoid using explicit names.
<UserControl x:Class="ErdBuilder.ErdMenuItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:erdBuilder="clr-namespace:ErdBuilder"
x:Name="UserControl"
DataContext="{Binding RelateSource={RelativeSource Self}}">

wpf binding text inside usercontrol text box from main window text box

main window
<TextBox x:Name="fbSearchBox" Margin="69,10,298,11" TextWrapping="Wrap" BorderBrush=" x:Null}"/>
<local:FacebookAutoComplete "want to set text from here of fbSearchBox" />
user control
<UserControl x:Class="ZuneWithCtrls.Pages.Facebook.Home.FacebookAutoComplete"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" Width="431" Height="49"
x:Name="uc">
<TextBlock x:Name="txtDynamicText"/>
</UserControl>
want to show text in txtdynamicText when type from fbSearchBox.. Plz help
You need some property in user control you can bind to.
Add a dependency property to your user control:
public static readonly DependencyProperty DynamicTextProperty =
DependencyProperty.Register(
"DynamicText",
typeof(string),
typeof(FacebookAutoComplete),
new FrameworkPropertyMetadata(null));
public string DynamicText
{
get { return (string)GetValue(DynamicTextProperty); }
set { SetValue(DynamicTextProperty, value); }
}
Bind a nested control inside user control to this dependency property:
<TextBlock x:Name="txtDynamicText"
Text="{Binding Path=DynamicText, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}"/>
Now you can bind FacebookAutoComplete.DynamicText to the TextBox from MainWindow:
<local:FacebookAutoComplete DynamicText="{Binding Text, ElementName=fbSearchBox, UpdateSourceTrigger=PropertyChanged}"/>

Categories