Binding control property to change it during runtime - c#

I'm preparing a some kind of a alphanumeric keyboard control for my project. Unfortunately I have faced a problem with dynamically changing a content of the button during the runtime. Here is an example code:
XAML
<UserControl x:Class="WpfApplication10.AlphaNumericKeyboard"
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:WpfApplication10"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
d:DesignHeight="300" d:DesignWidth="800">
<UserControl.Resources>
<local:LowerUpperCaseConverter x:Key="LowerUpperCaseConverter"/>
<Style TargetType="Button" x:Key="KeyboardButton">
<Setter Property="Width" Value="30"/>
<Setter Property="Height" Value="30"/>
<Setter Property="Background" Value="Black" />
<Setter Property="Foreground" Value="White" />
</Style>
<!--<local:YesNoToBooleanConverter x:Key="YesNoToBooleanConverter" />-->
<Style x:Key="KeyboardStyle" TargetType="{x:Type StackPanel}">
<Style.Resources>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource KeyboardButton}"/>
</Style.Resources>
<Setter Property="OverridesDefaultStyle" Value="True"/>
</Style>
</UserControl.Resources>
<StackPanel Background="Red" Style="{DynamicResource KeyboardStyle}">
<TextBox />
<StackPanel Orientation="Horizontal">
<Button Content="{Binding Path=IsUppercase, ConverterParameter=q, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=w, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=e, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=r, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=t, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=y, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=u, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=i, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=o, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=p, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Button Content="{Binding Path=IsUppercase, ConverterParameter=a, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=s, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=d, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=f, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=g, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=h, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=j, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=k, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=l, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Button Content="↑" Click="Button_Click"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=z, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=x, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=c, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=v, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=b, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=n, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
<Button Content="{Binding Path=IsUppercase, ConverterParameter=m, Converter={StaticResource LowerUpperCaseConverter}, Mode=TwoWay}"/>
</StackPanel>
</StackPanel>
CS
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace WpfApplication10
{
/// <summary>
/// Interaction logic for AlphaNumericKeyboard.xaml
/// </summary>
public partial class AlphaNumericKeyboard : UserControl
{
public bool IsUppercase { get; set; }
public AlphaNumericKeyboard()
{
//this.IsUppercase = true;
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.IsUppercase = !this.IsUppercase;
this.UpdateLayout();
}
}
//[ValueConversion(typeof(bool), typeof(string))]
public class LowerUpperCaseConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
return (bool)value ? parameter.ToString().ToUpper() : parameter.ToString().ToLower();
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
return true;
}
}
}
It is properly working when I run it. It displays upper or lowercase letters on buttons depending on IsUppercase property but only if it is set before InitializeComponents();. After that when I change the IsUppercase property by clicking an upward pointing arrow symbol it doesn't seem to take any effect.
So my question is: how to bind control property to change it during runtime?

You either need to implement a DependencyProperty or implement the INotifyPropertyChanged interface to update the UI controls from code behind.
Try this:
public partial class AlphaNumericKeyboard : UserControl, INotifyPropertyChanged
{
private bool isUppercase;
public bool IsUppercase
{
get { return isUppercase; }
set
{
isUppercase = value;
NotifyPropertyChanged("IsUppercase");
}
}
...
/// Implement INotifyPropertyChanged interface correctly
}
Please follow the link to find out how to correctly implement the INotifyPropertyChanged interface.

Related

WPF ComboBox bound with object list and display less different value in selected item than in the item list

I have this ComboBox:
<ComboBox
ItemsSource="{Binding imageFormats}">
<ComboBox.ItemTemplate>
<DataTemplate>
<DockPanel>
<TextBlock DockPanel.Dock="Left" Text="{Binding Extension}" />
<TextBlock DockPanel.Dock="Left" Text=" - " />
<TextBlock DockPanel.Dock="Right" Text="{Binding Description}" />
</DockPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Which is bound to this list:
private List<ImageFormatModel> imageFormats = new List<ImageFormatModel>();
public MainWindow()
{
ComboBoxImages.ItemsSource = imageFormats;
}
The Object ImageFormatModel consists of two strings:
public class ImageFormatModel
{
public string Extension { get; set; }
public string Description { get; set; }
}
Is possible that the selected item shows only the extension but in the dropdown menu both are shown?
Both values should be shown in this menu:
But if I select one, only the extension should be visible. Not like this:
You could apply a Style with a DataTrigger to the TextBlock elements to be hidden:
<DataTemplate>
<DockPanel>
<DockPanel.Resources>
<Style x:Key="tbStyle" TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=ComboBoxItem}}" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</DockPanel.Resources>
<TextBlock DockPanel.Dock="Left" Text="{Binding Extension}" />
<TextBlock DockPanel.Dock="Left" Text=" - " Style="{StaticResource tbStyle}" />
<TextBlock DockPanel.Dock="Right" Text="{Binding Description}" Style="{StaticResource tbStyle}" />
</DockPanel>
</DataTemplate>

How can I set ComboboxItem isEnable property with binding?

I have a model view and a property called isEnable and I would like to set the comboboxItem IsEnable property with binding to property created in the model view , the problem is that I have datatemplate created inside a combobox , so it's not a simple Combobox , this is my code:
<ComboBox x:Name="ComboBoxUsers" ItemsSource="{Binding Users}" FontFamily="Arial" FontSize="11" Grid.Row="3" Height="30" Margin="10,5,5,5">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<Image />
<TextBlock />
</StackPanel>
<DataTemplate.Resources>
<Style TargetType="ComboBoxItem">
<Setter Property="IsEnable" Value="{Binding IsEnable}"/>
</Style>
</DataTemplate.Resources>
</DataTemplate>
</ComboBox.ItemTemplate>
Simple Class of Users:
public class Users
{
public string Name { get; set; }
public bool IsEnable { get; set; }
public Users()
{
}
}
How can I achieve that?
I solved my problem by adding this code :
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem"
<Setter Property="IsEnable" Value="{Binding IsEnable}" />
</Style>
</ComboBox.ItemContainerStyle>
So the complete code will be :
<ComboBox x:Name="ComboBoxUsers" ItemsSource="{Binding Users}" FontFamily="Arial" FontSize="11" Grid.Row="3" Height="30" Margin="10,5,5,5">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<Image />
<TextBlock />
</StackPanel>
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem" >
<Setter Property="IsEnable" Value="{Binding IsEnable}" />
</Style>
</ComboBox.ItemContainerStyle>
</DataTemplate>
</ComboBox.ItemTemplate>

Using IValueConverter to enable button

I am trying to learn how to use the IValueConverter to enable/disable controls (in this case a button) using the boolean-property of an item selected in a listbox. The button in question is the "TestButton". I believe I have the XAML for it setup correctly but it does not enable when I add and select a user defined item or disable when I select one of the other items in the listbox. The listbox contains a list of "Drink" objects that can be added to. When one is added it becomes a user defined item. Now I believe I am missing something but I am not sure what. Any help will be appreciated.
ViewModel code here:
<Window x:Class="WpfApp1.MainWindow"
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:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<local:Drinks x:Key="Drink"/>
<local:EnableConverter x:Key="EnableConverter"/>
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
<ControlTemplate x:Key="validationTemplate">
<DockPanel>
<TextBlock Foreground="Red" FontSize="20">!</TextBlock>
<AdornedElementPlaceholder/>
</DockPanel>
</ControlTemplate>
<Style x:Key="textStyleTextBox" TargetType="TextBox">
<Setter Property="Foreground" Value="#333333" />
<Setter Property="MaxLength" Value="40" />
<Setter Property="Width" Value="392" />
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ListBox x:Name="DrinksListBox" HorizontalAlignment="Center" Height="325" Width="275" Margin="0,0,0,0" VerticalAlignment="Center" Grid.Column="0" ItemsSource="{Binding SomeDrinks}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="0,2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Type}" Width="80" Margin="0,0,10,0" Grid.Column="0"/>
<TextBlock Text="{Binding Name}" Width="80" Margin="0,0,10,0" Grid.Column="1" HorizontalAlignment="Left"/>
<TextBlock Text="{Binding NumberOfCans}" Width="80" Margin="0,0,10,0" Grid.Column="2" HorizontalAlignment="Left"/>
<Button x:Name="DrinkDeleteButton" Content="Delete" Visibility="{Binding Path=IsUserDefined, Converter={StaticResource BoolToVis}}" Click="CmdDeleteDrink_Clicked" HorizontalAlignment="Left" Grid.Column="3"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBox x:Name="DrinkNameTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="45" Margin="0,0,0,100" TextWrapping="Wrap" Text="Enter Drink Name" VerticalAlignment="Center" Width="240" FontSize="20" VerticalContentAlignment="Center"/>
<TextBox x:Name="NumberCansTextBox" Style="{StaticResource textStyleTextBox}" Grid.Column="1" HorizontalAlignment="Left" Height="45" Margin="0,0,0,150" VerticalAlignment="Bottom" Width="240" FontSize="20" VerticalContentAlignment="Center">
<TextBox.Text>
<Binding Path="NumberOfCans" UpdateSourceTrigger="PropertyChanged" Source="{StaticResource Drink}">
<Binding.ValidationRules>
<local:NumberCansValidationRule Min="0" Max="10"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<ComboBox x:Name="DrinkTypeComboBox" Grid.Column="1" HorizontalAlignment="Left" Margin="0,47,0,0" VerticalAlignment="Top" Width="240" Height="45" ItemsSource="{Binding Drinks, Mode=OneWay}" DisplayMemberPath="Type" FontSize="20"/>
<Button x:Name="AddDrinkButton" Content="Add Drink" Grid.Column="1" HorizontalAlignment="Right" Margin="0,0,10,100" VerticalAlignment="Center" Width="100" Height="45" Click="CmdAddDrink_Clicked">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="IsEnabled" Value="False"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=(Validation.HasError), ElementName=NumberCansTextBox}" Value="False"/>
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="True"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<Button x:Name="TestButton" Content="Test" IsEnabled="{Binding Path=IsUserDefined, UpdateSourceTrigger=PropertyChanged, Source={StaticResource Drink}, Converter={StaticResource EnableConverter}}" Grid.Column="1" HorizontalAlignment="Right" Margin="0,70,10,0" VerticalAlignment="Center" Width="100" Height="45"/>
</Grid>
Here is my converter:
namespace WpfApp1
{
class EnableConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool isenable = false;
bool b = (bool)value;
if (b == true)
{
isenable = true;
}
return isenable;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
This class contains the "IsUserDefined" property that I am binding to:
public class Drinks
{
private string type;
private string name;
private int numCans;
public Drinks() { }
public Drinks(string type, string name, int numCans)
{
this.type = type;
this.name = name;
this.numCans = numCans;
}
public bool IsUserDefined { get; set; }
public string Type
{
get { return type; }
set
{
if (type != value)
{
type = value;
}
}
}
public string Name
{
get { return name; }
set
{
if (name != value)
{
name = value;
}
}
}
public int NumberOfCans
{
get { return numCans; }
set
{
if (numCans != value)
{
numCans = value;
}
}
}
}

Button inside listview c#

I've successfully put a button inside each listview item. But I want to obtain the Item on which the button is.. In this case each item is a Friend and has a button on click of the button I want to now which friend it is. How can I achieve this?
VIEW
<ListView x:Name="dataGrid" ItemsSource="{Binding Friends}" Height="314" BorderThickness="0" SelectedItem="{Binding SelectedItemFriends}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="Resources\Images\ic_status.png" Height="24" Width="18"/>
<StackPanel Margin="5" Orientation="Vertical">
<TextBlock FontWeight="Bold" Text="{Binding name}"/>
<StackPanel x:Name="RemoveItems" Margin="5" Orientation="Vertical">
<TextBlock Text="{Binding lastLocation}"/>
<TextBlock Text="{Binding timestamp}"/>
</StackPanel>
<StackPanel x:Name="AdditionItems" Margin="5" Orientation="Vertical" Visibility="Collapsed">
<TextBlock Text="{Binding Path=loc.area}"/>
<TextBlock Text="{Binding Path=loc.building}"/>
<TextBlock Text="{Binding Path=loc.floor}"/>
<TextBlock Text="{Binding Path=loc.room}"/>
</StackPanel>
</StackPanel>
<Button Style="{DynamicResource FlatButtonStyle}" Command="{Binding DataContext.SelectViewCommand, ElementName=GeneralWindowView}" CommandParameter="ChatViewModel" x:Name="button1" Content="Chat" Margin="10">
<Button.Template>
<ControlTemplate>
<Image Source="Resources\Images\chat_image.png"/>
</ControlTemplate>
</Button.Template>
</Button>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}, Path=IsSelected}" Value="true">
<Setter TargetName="AdditionItems" Property="Visibility" Value="Visible"/>
<Setter TargetName="RemoveItems" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Best regards,
Antoine
You can bind the CommandParameter to the ListViewItem to which the Button belongs. Something like:
<Button x:Name="button1"
Command="{Binding DataContext.SelectViewCommand,
ElementName=GeneralWindowView}"
CommandParameter="{Binding}">
In this way, the CommandParameter is always the ViewModel of the ListViewItem on which the Button stays.
As a side node, I think that if the SelectViewCommand deals with the current ListViewItem, maybe the Command should stay on the ViewModel of the ListViewItem, not the one on the GeneralWindowView...
Any way, hope this helps.
You could do something like this....
class Friend
{
// Other properties......
public string Link_1 { get; set; }
}
set Link_1 = "ChatViewModel" somewhere
XAML
<Button x:Name="button1" Command="{Binding DataContext.SelectViewCommand, ElementName=GeneralWindowView}" CommandParameter="{Binding}">
then in your SelectViewCommand Command handler
public void OnSelectViewCommand (dynamic obj)
{
this.Current_ViewModel = this.GetViewModel(obj.Link_1);
}
EDIT........
There is another way that directly addresses the issue of sending multiple parameters in the CommandParameter...
XAML
add the manespace
xmlns:Converters="clr-namespace:CommandParameterExample.Converters"
add the Resource
<UserControl.Resources>
<Converters:CommandParameter_Converter x:Key="CommandParameter_Converter" />
</UserControl.Resources>
Add a hidden Text Block
<TextBlock Visibility="Collapsed" Name="VM" Text="ChatViewModel"></TextBlock>
Here is your Button
<Button Content="Chat" Command="{Binding DataContext.SelectViewCommand, ElementName=GeneralWindowView}" >
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource CommandParameter_Converter}">
<Binding/>
<Binding Path="Text" ElementName="VM"/>
</MultiBinding>
</Button.CommandParameter>
</Button>
Here is the CommandParameter_Converter
class CommandParameter_Converter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return values.Clone(); // simply return an array
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
and here is your SelectViewCommand
public void OnSelectViewCommand (object parameter)
{
var values = (object[])parameter;
var FriendObject = (dynamic)values[0];
var ViewModelName = (string)values[1];
}
This is the correct way to resolve your issue (sending 2 arguments in CommandParameter). But as you can see, it's rather involved....

How to display a control dynamically in wpf?

I have a collection with fields cityname, statename and countryname and I bind that collection to my wpf form. I want to display the cityname in a Textbox, the statename in a combobox and the countryname in a combobox. All the textboxes and comboboxes should come dynamically. How can I do this job?
Any one suggest me how to design this form dynamically in wpf using MVVM
I am trying to do this code but not get result properly
<UserControl.Resources>
<DataTemplate x:Key="IntegerTemplate">
<DockPanel>
<TextBox Margin="10,0,0,0" x:Name="IntegerTemplate" Grid.Column="1" MaxLength="{Binding Path=CardField.MaximumLength}" Text="{Binding Path=CardField.FieldData, Mode=TwoWay}" />
</DockPanel>
</DataTemplate>
<DataTemplate x:Key="StringTemplate">
<DockPanel>
<ComboBox Margin="10,0,0,0" x:Name="cmbFieldData" Grid.Column="1" Text="{Binding Path=CardField.FieldData, Mode=TwoWay}" />
</DockPanel>
</DataTemplate>
<DataTemplate x:Key="DefaultTemplate">
</DataTemplate>
<DataTemplate x:Key="dataTemplate">
<ContentControl x:Name="MyContentControl" Content="{Binding}" ContentTemplate="{StaticResource DefaultTemplate}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=CardField.FieldTag}" Value="City">
<Setter TargetName="MyContentControl" Property="ContentTemplate"
Value="{StaticResource IntegerTemplate}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=CardField.FieldTag}" Value="State">
<Setter TargetName="MyContentControl" Property="ContentTemplate"
Value="{StaticResource StringTemplate}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=CardField.FieldTag}" Value="Country">
<Setter TargetName="MyContentControl" Property="ContentTemplate"
Value="{StaticResource StringTemplate}" />
</DataTrigger>
<!-- and so on -->
</DataTemplate.Triggers>
</DataTemplate>
</UserControl.Resources>
we are using this code in our xaml page
<ItemsControl x:Name="items"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource dataTemplate}"
/>
UPDATE:
i am trying to do this following code:
<TextBlock x:Name="tbFieldTag" Cursor="Hand" VerticalAlignment="Center" HorizontalAlignment="Stretch" TextWrapping="Wrap" Margin="10,0,0,0" Text="{Binding Path=CardField.FieldTag}" />
<ItemsControl x:Name="items"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource dataTemplate}"/>
In that i got Value of TextBlock but i am not getting the value in ItemTemplate. so where I doing wrong?
Try this:
1) data template selector
public class CardFieldTemplateSelector : IValueConverter
{
public DataTemplate CityNameTemplate { get; set; }
public DataTemplate StateNameTemplate { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string fieldTag = (string) value;
switch (fieldTag)
{
case "City":
return CityNameTemplate;
case "State":
return StateNameTemplate;
}
throw new ArgumentOutOfRangeException();
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
2) XAML:
<selectors:CardFieldTemplateSelector x:Key="cardFieldTemplateSelector">
<selectors:CardFieldTemplateSelector.CityNameTemplate>
<DataTemplate>
<DockPanel>
<TextBox Margin="10,0,0,0" x:Name="IntegerTemplate" Grid.Column="1" MaxLength="{Binding Path=CardField.MaximumLength}" Text="{Binding Path=CardField.FieldData, Mode=TwoWay}" />
</DockPanel>
</DataTemplate>
</selectors:CardFieldTemplateSelector.CityNameTemplate>
<selectors:CardFieldTemplateSelector.StateNameTemplate>
<DataTemplate>
<DockPanel>
<ComboBox Margin="10,0,0,0" x:Name="cmbFieldData" Grid.Column="1" Text="{Binding Path=CardField.FieldData, Mode=TwoWay}" />
</DockPanel>
</DataTemplate>
</selectors:CardFieldTemplateSelector.StateNameTemplate>
</selectors:CardFieldTemplateSelector>
<DataTemplate x:Key="dataTemplate">
<ContentControl x:Name="MyContentControl"
Content="{Binding}"
ContentTemplate="{Binding CardField.FieldTag, Converter={StaticResource cardFieldTemplateSelector}"/>
</DataTemplate>
<ItemsControl x:Name="items"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource dataTemplate}"/>
Why can;t you use the WPF Data Form from Codeplex.
You can add custom editors in this form, based on the data types.
Hope this help.

Categories

Resources