Cross-binding checkboxes - isChecked #1 -> isEnabled #2 - c#

I have a ListBox that takes boolean elements from list in my model and represent them as checkboxes. Just after building project the second checkbox isEnabled is set to false. If I modify (eg. cut and paste same converter) binding in the second checkbox in debug, the binding start working correctly. Also I have a global checkboxes that modyfi isChecked properties of all checkboxes from listBox. If I set globalCheckbox #2, all listBox_checkBoxes #2 are set to true and all listBox_checkBoxes #1 isEnabled property are set to false
XAML:
<ListBox x:Name="ListBox_assent" SelectedIndex="-1" Grid.Row="2" ItemsSource="{Binding Path=FullDataAssetList.List}" IsSynchronizedWithCurrentItem="True" Height="Auto">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource MaterialDesignListBoxItem}">
<Setter Property="Margin" Value="2"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Focusable" Value="False" />
<EventSetter Event="RequestBringIntoView" Handler="ListBoxItem_RequestBringIntoView"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Grid.Row="0" Opacity="{Binding Path=SkipAssentTemp, Converter={StaticResource BoolToOpacity}}">
<StackPanel Orientation="Horizontal" Grid.Row="0" Grid.Column="3">
<CheckBox x:Name="chbx_Assent" HorizontalContentAlignment="Left" FlowDirection="RightToLeft" ToolTip="Skip" IsChecked="{Binding SkipAssent, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding SkipAssentTemp, Converter={StaticResource InverseBoolean}}" LostFocus="chbx_Assent_LostFocus" Background="#FFCB0000"/>
<TextBlock FontSize="16" Text=" / " VerticalAlignment="Center"/>
<CheckBox x:Name="chbx_AssentTemp" HorizontalContentAlignment="Left" FlowDirection="RightToLeft" ToolTip="Skip temp." IsChecked="{Binding SkipAssentTemp, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding SkipAssent, Converter={StaticResource InverseBoolean}}" LostFocus="chbx_AssentTemp_LostFocus" Background="#FFCBA300"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
Converter:
public class InverseBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (targetType == typeof(bool) || targetType == typeof(bool?))
{
if ((bool?)value == true)
{
return false;
}
else
if ((bool?)value == false)
{
return true;
}
return null;
}
else
{
throw new InvalidOperationException("The target must be a boolean");
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotSupportedException();
}
}
How can i fix binding to get full functionality just after building?

I have found solution. DataTrigger in xaml was overwritnig isEnabled property

Related

Replacing delete button with restore depending on boolean value in WPF

I have boolean column named "deleted" in mysql.
1)if the row is not deleted it shows the delete button.
2)if the row is deleted it should display retore button in that datagrid cell instead of deleted with the query of restore behind it.
right now i can only disable the button if the row is deleted.
My code is as follows.
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Delete" Name="btnDelete"
Click="btnDelete_Click">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding deleted}" Value="False">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
The main idea is using converter that will convert bool value to visibility.
However, for restore button, you will need to invert the visibility behavior, therefore custom converter comes in mind
public class BoolToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (!(value is bool boolValue))
throw new InvalidOperationException();
if (parameter == null || (parameter is bool invertVisibility && !invertVisibility))
return boolValue ? Visibility.Visible : Visibility.Collapsed;
else
return boolValue ? Visibility.Collapsed : Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Then your buttons will use the same converter registered as:
<Window.Resources>
<local:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"></local:BoolToVisibilityConverter>
</Window.Resources>
But one of them will pass additional parameter so that converter will invert its logic:
<Button Margin="5" Content="Delete"
Visibility="{Binding deleted, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=true}"
Command="{Binding DeleteCommand}"></Button>
<Button Margin="5" Content="Restore"
Visibility="{Binding deleted, Converter={StaticResource BoolToVisibilityConverter}}"
Command="{Binding RestoreCommand}"></Button>
You can use the built-in BoolToVisibilityConverter and set the Visibility Property, you might not need a trigger for this
...
<Window.Resources>
<BooleanToVisibilityConverter x:Key="VisibleIfTrueConverter" />
</Window.Resources>
...
<Button Visibility={Binding deleted, Converter={StaticResource VisibleIfTrueConverter}}/>

Change button tooltip with style - WPF

I have a DataGrid loaded with a list of objects that have a property bool IsAutomaticSell. I need that when changing the value, the tooltip of the button of that row is updated. I have the following code but it does not work. Thx
View.xaml
<DataGridTextColumn Header="Code"
Binding="{Binding Code}" />
<DataGridTemplateColumn Header="Actions"
Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center">
<Button Command="{Binding DataContext.AutomaticSellCommand,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"
CommandParameter="{Binding}"
Padding="10"
Margin="0,2,2,2">
<iconPacks:PackIconModern Kind="CurrencyDollar" />
<Button.Style>
<Style TargetType="{x:Type Button}"
BasedOn="{StaticResource AccentedSquareButtonStyle}">
<Setter Property="ToolTip"
Value="DEFAULT_TOOLTIP" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsAutomaticSell, UpdateSourceTrigger=PropertyChanged}"
Value="True">
<Setter Property="ToolTip"
Value="NEW_TOOLTIP" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
ViewModel.cs
public ICommand AutomaticSellCommand => _automaticSellCommand ??
(_automaticSellCommand = new RelayCommand<OrderStatusDataWrapper>(AutomaticSell));
private static void AutomaticSell(OrderStatusDataWrapper orderStatusData)
{
orderStatusData.IsAutomaticSell = !orderStatusData.IsAutomaticSell;
}
Bind ToolTip.
XAML:
<Button ToolTip={Binding ToolTip}" ... />
ViewModel:
public string ToolTip => (IsAutomaticSell) ? "DEFAULT_TOOLTIP" : "NEW_TOOLTIP";
You need to implement a ValueConverter in order to get this to work.
A ValueConverter will allow you to handle what to display based on your boolean value.
MSDN
public class BoolToContentConverter : IValueConverter
{
public BoolToContentConverter()
{
TrueContent = "True Tool Tip";
FalseContent = "False Tool Tip";
NullContent = "No Value";
}
public object TrueContent { get; set; }
public object FalseContent { get; set; }
public object NullContent { get; set; }
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
if (value == null)
return NullContent;
bool boolValue = true;
bool isBool = true;
try
{
boolValue = (bool) value;
}
catch
{
isBool = false;
}
if (!isBool)
return NullContent;
return boolValue ? TrueContent : FalseContent;
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
In your XAML you need to implement that converter.
<Window x:Class="Example.MainWindow"
...
xmlns:l="clr-Example"
...>
<Window.Resources>
<l:BoolToContentConverter x:Key="converter" />
</Window.Resources>
...
<DataGridTextColumn Header="Code"
Binding="{Binding Code}" />
<DataGridTemplateColumn Header="Actions"
Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center">
<Button Command="{Binding DataContext.AutomaticSellCommand,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"
CommandParameter="{Binding}"
Padding="10"
Margin="0,2,2,2">
<iconPacks:PackIconModern Kind="CurrencyDollar" />
<Button.Style>
<Style TargetType="{x:Type Button}"
BasedOn="{StaticResource AccentedSquareButtonStyle}">
<Setter Property="ToolTip"
Value="DEFAULT_TOOLTIP" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsAutomaticSell, UpdateSourceTrigger=PropertyChanged}"
Value="True">
<Setter Property="ToolTip"
Value="{Binding IsAutomaticSell, Converter={StaticResource converter}}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
....
</Window>
Hope this answers your question. Cheers!

Different template for selected item in WPF combobox than items in composite collection

I have a composite collection which consists of:
combobox item with content 'Select a vendor'
collection container with collection of Vendor objects, bound to a combobox cmbVendor
When a vendor is selected from the combobox, the ToString() method is called.
However, I want to display the value of the property Name of the selected Vendor object.
Setting the combobox property DisplayMemberPath='Name' works but then the 'Select a vendor' is not shown anymore on load, which is not desired.
Notes:
sometimes a Vendor object is chosen from code-behind
I can not override ToString() method of a Vendor object for other reasons
Any suggestions?
XAML
<UserControl.Resources>
<converters:VendorConverter x:Key='VendorConverter' />
<CollectionViewSource x:Key='VendorsCollection'
Source='{Binding Vendors}'>
</CollectionViewSource>
</UserControl.Resources>
<Grid>
<ComboBox Name='cmbVendor'
SelectedItem='{Binding Vendor, Converter={StaticResource VendorConverter}, Mode=TwoWay}'
IsSynchronizedWithCurrentItem='True'
IsEditable='True'
Width='{DynamicResource VendorCmbWidth}'>
<!--Make sure "Select a vendor" is selected-->
<i:Interaction.Behaviors>
<behaviour:SelectFirstItemBehavior />
</i:Interaction.Behaviors>
<ComboBox.Resources>
<DataTemplate DataType='{x:Type objects:Vendor}'>
<StackPanel Orientation='Horizontal'>
<TextBlock Text='{Binding Name}' />
</StackPanel>
</DataTemplate>
<DataTemplate DataType='{x:Type system:String}'>
<StackPanel Orientation='Horizontal'>
<TextBlock Text='{Binding }' />
</StackPanel>
</DataTemplate>
</ComboBox.Resources>
<ComboBox.ItemsSource>
<CompositeCollection>
<ComboBoxItem Content='Select a vendor' />
<CollectionContainer Collection='{Binding Source={StaticResource VendorsCollection}}' />
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>
</Grid>
</UserControl>
VendorConverter
internal class VendorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var vendor = value as Vendor;
if (vendor != null)
{
return vendor;
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var comboboxItem = value as ComboBoxItem;
if (comboboxItem != null)
{
return null;
}
var vendor = value as Vendor;
if (vendor != null)
{
return vendor;
}
return null;
}
}
Behaviors
internal class SelectFirstItemBehavior : Behavior<ComboBox>
{
protected override void OnAttached()
{
AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged;
}
protected override void OnDetaching()
{
AssociatedObject.SelectionChanged -= AssociatedObject_SelectionChanged;
base.OnDetaching();
}
private void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var combobox = sender as ComboBox;
if (combobox != null && combobox.SelectedIndex == -1)
{
combobox.SelectedIndex = 0;
}
}
}
Approach 1
You should be able to combine TextSearch.TextPath="Name" for your normal items and TextSearch.Text="Select a vendor" directly assigned to your special item:
<ComboBox
IsEditable="True"
TextSearch.TextPath="Name">
...
and
<CompositeCollection>
<ComboBoxItem Content='Select a vendor' TextSearch.Text="Select a vendor" />
<CollectionContainer Collection='{Binding Source={StaticResource VendorsCollection}}' />
</CompositeCollection>
Approach 2
Just display a visual hint text when nothing is selected:
<ComboBox
ItemsSource="{Binding Source={StaticResource VendorsCollection}}"
IsEditable="True">
<ComboBox.Style>
<Style TargetType="ComboBox">
<Style.Resources>
<VisualBrush x:Key="hintText" x:Shared="False" AlignmentX="Left" Stretch="None">
<VisualBrush.Visual>
<Grid Background="White">
<TextBlock Margin="4 3" Text="Select a vendor"/>
</Grid>
</VisualBrush.Visual>
</VisualBrush>
</Style.Resources>
<Style.Triggers>
<Trigger Property="Text" Value="">
<Setter Property="Background" Value="{StaticResource hintText}"/>
</Trigger>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Background" Value="{StaticResource hintText}"/>
</Trigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
</ComboBox>
This way, you can keep your items collection clean of extra entries and use TextSearch.TextPath and similar properties for your actual items.

WPF - Disable tooltip when value is null or empty

I have this problem, i'm using telerik on WPF and a source on my grid and doing the correct bindings. I want to be able to disable the tooltip when the value of the binding is null or empty. How can it be done?
This is one example:
<telerik:GridViewDataColumn x:Name="GRIDVIEWCOLUMN_ENDDATE" Header="Data de Conclusão" DataMemberBinding="{Binding ClosedDate, StringFormat=dd-MM-yyyy}" IsVisible="False" Width="auto" IsFilterable="False">
<telerik:GridViewDataColumn.ToolTipTemplate>
<DataTemplate>
<TextBlock Text="{Binding ClosedDate, StringFormat=dd-MM-yyyy}" FontFamily="Segoe UI Light" FontSize="13.667" />
</DataTemplate>
</telerik:GridViewDataColumn.ToolTipTemplate>
</telerik:GridViewDataColumn>
Just bind the Visibility of your tooltip (in this case, you have provided a TextBlock) to the same property - ClosedDate, and use a converter to get the value based on your logic.
public class TooltipVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
if (value is string)
{
return String.IsNullOrEmpty(value as string) ? Visibility.Collapsed :Visibility.Visible;
}
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
In your XAML, you would have something like this. You declare your converter as a static resource somewhere in your view, and later refer to it in your binding.
<converters:TooltipVisibilityConverter x:Key="TooltipVisibilityConverter"/>
<telerik:GridViewDataColumn x:Name="GRIDVIEWCOLUMN_ENDDATE" Header="Data de Conclusão" DataMemberBinding="{Binding ClosedDate, StringFormat=dd-MM-yyyy}" IsVisible="False" Width="auto" IsFilterable="False">
<telerik:GridViewDataColumn.ToolTipTemplate>
<DataTemplate>
<TextBlock Text="{Binding ClosedDate, StringFormat=dd-MM-yyyy}" FontFamily="Segoe UI Light" FontSize="13.667" Visibility="{Binding ClosedDate, Converter={StaticResource x:Key="TooltipVisibilityConverter"}" />
</DataTemplate>
</telerik:GridViewDataColumn.ToolTipTemplate>
I know this is a pretty old question but I was trying to hide empty tooltips and found a much simpler way to do so here: http://wpfthoughts.blogspot.com/2014/02/hiding-empty-tooltips.html.
Basically if you put a resource dictionary in App.xaml you can automatically hide all empty/null tooltips in your application.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Style TargetType="{x:Type ToolTip}">
<Style.Triggers>
<Trigger Property="Content" Value="{x:Static sys:String.Empty}">
<Setter Property="Visibility" Value="Collapsed"/>
</Trigger>
<Trigger Property="Content" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
It is overkill if you only need it in one spot but it's a super simple fix that prevents you from having to add code to every page that has tooltips. Hopefully this helps someone out.
You can consider using a IValueConverter to show/hide the tooltip border
<telerik:GridViewDataColumn x:Name="GRIDVIEWCOLUMN_ENDDATE" Header="Data de Conclusão" DataMemberBinding="{Binding ClosedDate, StringFormat=dd-MM-yyyy}" IsVisible="False" Width="auto" IsFilterable="False">
<telerik:GridViewDataColumn.ToolTipTemplate>
<DataTemplate>
<Border Background="Black" Visibility="{Binding ClosedDate, Converter={StaticResource BorderVisible}}" >
<TextBlock Text="{Binding ClosedDate, StringFormat=dd-MM-yyyy}" FontFamily="Segoe UI Light" FontSize="13.667" />
</Border>
</DataTemplate>
</telerik:GridViewDataColumn.ToolTipTemplate>
</telerik:GridViewDataColumn>
class BorderVisibilitySetter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
//check if the control's content property is null or empty
if(value == null || value.ToString() == string.Empty)
return Visibility.Collapsed;
else
return Visibility.Visible;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Setting the tooltip parent control IsEnabled to false will effectively prevent the tooltip to pop unless ToolTipService.ShowOnDisabled is set to true.
Check george.zakaryan's answer, but instead of using a converter to bind the visibility of the tooltip textblock to its content, use a similar converter to Bind the IsEnabled property of the tooltip's parent to its Textblock's text.
public class StringToBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is string)
{
return String.IsNullOrEmpty(value as string) ? false : true;
}
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
in your xaml
<UserControl.Resources>
<utils:StringToBoolConverter x:Key="StringToBoolConverter"/>
</UserControl.Resources>
and
<TextBlock Text="{Binding SrcDrive, Mode=OneWay}" IsEnabled="{Binding SrcDrive, Converter={StaticResource StringToBoolConverter}, Mode=OneWay}" Width="400" >
<TextBlock.ToolTip>
<TextBlock Text="{Binding SrcDrive, Mode=OneWay}" />
</TextBlock.ToolTip>
</TextBlock>
Native Telerik tooltip for GridView has a defect, which is even when you set Visibility=Collapsed it will still show an empty box (see below image):
Code:
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Name}">
<telerik:GridViewColumn.ToolTipTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" Visibility="Collapsed" />
</DataTemplate>
</telerik:GridViewColumn.ToolTipTemplate>
</telerik:GridViewDataColumn>
</telerik:RadGridView.Columns>
Result:
Solution:
Instead of using null check Converter, the approach that worked for me was to skip showing the tooltip when TextBlock.ToolTipOpeningEvent is triggering.
To do so in your xaml.cs do the following:
public partial class MainWindow: Window
{
public MainWindow()
{
InitializeComponent();
EventManager.RegisterClassHandler(typeof(GridViewCell),
TextBlock.ToolTipOpeningEvent,
new RoutedEventHandler(OnToolTipOpening));
}
private void OnToolTipOpening(object sender, RoutedEventArgs e)
{
if (sender is GridViewCell cell) // show tooltip only when text is trimmed
e.Handled = !IsTextTrimmed(cell);
}
static bool IsTextTrimmed(GridViewCell cell) => cell?.Value.ToString().Length > 50;
}
That's it, and no need to write any additional logic to show/hide tooltips.

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