I am adding controls to grid rows based on the data type. I have grid in a tab control when I switch the tab away from Grid tab and come back all the controls in the rows are messed up.
Here is my sample code..
Any response will be appreciated.
Presentation Model
using System;using System.Collections.ObjectModel;using System.ComponentModel;using System.Windows.Data;
namespace PropertiesTest{ public class PropertiesPMod : INotifyPropertyChanged { ObservableCollection<Employee> _Employees; private ObservableCollection<PropertyWrapper> _PropertyWrapper;
public PropertiesPMod() { LoadEmployees(); LoadProperties(); }
public ObservableCollection<Employee> Employees { get { return _Employees; } set { _Employees = value; RaisePropertyChanged("Employees"); } }
public ObservableCollection<PropertyWrapper> PropertyWrapper { get { return _PropertyWrapper; } set { _PropertyWrapper = value; RaisePropertyChanged("PropertyWrapper"); } }
private void LoadEmployees() { Employees = new ObservableCollection<Employee>(); Employees.Add(new Employee("Scott", "Meyer")); Employees.Add(new Employee("Chad", "Rust")); Employees.Add(new Employee("Doug", "Rom")); Employees.Add(new Employee("Laxman", "Rawat"));
}
private void LoadProperties() { PropertyWrapper = new ObservableCollection<PropertyWrapper>();
PropertyWrapper.Add(new PropertyWrapper() { Name="Include In-House patients",ExposedValue="True",SqlDataType="bit",Description="In house patient",IsRequired=true,MustSelectFromList=false});
PropertyWrapper.Add(new PropertyWrapper() { Name = "Include InPatient data", ExposedValue = "False", SqlDataType = "bit", Description = "Include inpatient data", IsRequired = true, MustSelectFromList = false });
PropertyWrapper.Add(new PropertyWrapper() { Name = "Include OutPatient patients", ExposedValue = "True", SqlDataType = "bit", Description = "Include outpatient data", IsRequired = true, MustSelectFromList = false });
PropertyWrapper.Add(new PropertyWrapper() { Name = "Start Date", ExposedValue = "12/12/2009", SqlDataType = "Date", Description = "Paient start date", IsRequired = true, MustSelectFromList = false });
PropertyWrapper.Add(new PropertyWrapper() { Name = "End Date", ExposedValue = "12/12/2010", SqlDataType = "Date", Description = "Patient end date", IsRequired = true, MustSelectFromList = false });
PropertyWrapper.Add(new PropertyWrapper() { Name = "physcian Name", ExposedValue = "Laxman", SqlDataType = "varchar", Description = "physcian name", IsRequired = true, MustSelectFromList = false });
PropertyWrapper.Add(new PropertyWrapper() { Name = "Day number", ExposedValue = "1", SqlDataType = "int", Description = "day number", IsRequired = true, MustSelectFromList = false });
PropertyWrapper.Add(new PropertyWrapper() { Name = "week number", ExposedValue = "4", SqlDataType = "int", Description = "week number", IsRequired = true, MustSelectFromList = false }); }
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
#endregion
public class Employee {
private string _FirstName; private string _LastName;
public Employee(string firstName, string lastName) { _FirstName = firstName; _LastName = lastName; }
public string FirstName { get { return _FirstName; } set { _LastName = value; }
public string LastName { get { return _LastName; } set { _LastName = value; }
} public class PropertyWrapper : INotifyPropertyChanged { #region Variables
private string _Message; private string _CodeDescription; private string _ExposedValue; private string _SqlDataType; private string _Value; private bool _IsRequired; private string _Name; private bool _MustSelectFromList; private string _MaxRange; private string _MinRange; private Guid? _CodeDescListID; private string _Description;
#region Properties
public int Sequence { get; set; }
public string Value { get { return _Value; } set { _Value = value; NotifyPropertyChanged("Value"); } }
public string CodeDescription { get { return _CodeDescription; } set { _CodeDescription = value; NotifyPropertyChanged("CodeDescription"); } }
public string ExposedValue { get { return _ExposedValue; } set { _ExposedValue = value;
NotifyPropertyChanged("ExposedValue"); } }
public bool IsRequired { get { return _IsRequired; } set { _IsRequired = value; NotifyPropertyChanged("IsRequired"); } }
public string Name { get { return _Name; } set { _Name = value; NotifyPropertyChanged("Name"); } }
public string SqlDataType { get; set; }
public bool MustSelectFromList { get { return _MustSelectFromList; } set { _MustSelectFromList = value; NotifyPropertyChanged("MustSelectFromList"); } }
public string MaxRange { get { return _MaxRange; } set { _MaxRange = value; NotifyPropertyChanged("MaxRange"); } }
public string MinRange { get { return _MinRange; } set { _MinRange = value; NotifyPropertyChanged("MinRange"); } }
public Guid? CodeDescListID { get { return _CodeDescListID; } set { _CodeDescListID = value; NotifyPropertyChanged("CodeDescListID"); } }
public string Description { get { return _Description; } set { _Description = value; NotifyPropertyChanged("Description"); } }
public int PredefinedFormatId { get; set; }
public int PredefinedFormatPropertyId { get; set; }
public int PredefinedFormatFieldId { get; set; }
public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(string propertyName) { if (PropertyChanged != null) PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
} }
public class ComboListStaticResource { private ObservableCollection<string> _ComboList;
public ObservableCollection<string> ComboList { get { return _ComboList; } }
public ComboListStaticResource() { _ComboList = new ObservableCollection<string> { "True", "False" }; } }
#region FormatConverters Members
public class BitFormatter : IValueConverter { public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) { switch ((string)value) { case "-1": return "True"; case "1": return "True"; case "0": return "False"; case "False": case "True": return value; default: return "True"; } }
public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) { switch ((string)value) { case "False": return 0; case "True": return -1; default: return 0; } } }
public class IntFormatter : IValueConverter { public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) { return !String.IsNullOrEmpty(System.Convert.ToString(value).Trim()) ? System.Convert.ToDouble((string)value) : (System.Convert.ToString(parameter) == "MaxRange" ? System.Convert.ToDouble("+2,147,483,648") : System.Convert.ToDouble("-2,147,483,648")); }
public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) { return value; } }
public class FloatFormatter : IValueConverter {
public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) { return !String.IsNullOrEmpty(System.Convert.ToString(value).Trim()) ? System.Convert.ToDouble((string)value) : (System.Convert.ToString(parameter) == "MaxRange" ? System.Convert.ToDouble("+2,147,483,648") : System.Convert.ToDouble("-2,147,483,648")); }
public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) { return value; }
public class MustSelectFormatter : IValueConverter {
public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) { return (bool)value == false; }
public class MandatoryFormatter : IValueConverter {
public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) { return (bool)value ? "*" : ""; }
public class ComboValueConverter : IValueConverter {
public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) { var items = new ObservableCollection<string> { "True", "False" }; return items; }
public class DateTimeConverter : IValueConverter { public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value.ToString().ToUpper() == "Now") return DateTime.Now.ToString(); return value; }
View.xaml
<UserControl x:Class="PropertiesTest.MainPage" 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" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400" xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls" xmlns:igGrid="clr-namespace:Infragistics.Controls.Grids;assembly=InfragisticsSL4.Controls.Grids.XamGrid.v10.3" xmlns:ViewModels="clr-namespace:PropertiesTest" xmlns:inputToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit">
<UserControl.Resources>
<ViewModels:MustSelectFormatter x:Key="MustSelectFormatter" /> <ViewModels:DateTimeConverter x:Key="DateTimeConverter" /> <ViewModels:IntFormatter x:Key="IntFormatter" /> <ViewModels:FloatFormatter x:Key="FloatFormatter" /> <ViewModels:BitFormatter x:Key="BitFormatter" /> <ViewModels:MandatoryFormatter x:Key="MandatoryFormatter" /> <ViewModels:ComboValueConverter x:Key="ComboValueConverter" /> <ViewModels:ComboListStaticResource x:Key="ComboList" />
<DataTemplate x:Key="ColMustSelectText"> <TextBox Name="Textbox" Text="{Binding ExposedValue, Mode=TwoWay}" HorizontalContentAlignment="Stretch" IsReadOnly="True"></TextBox> </DataTemplate>
<DataTemplate x:Key="Colcombobox"> <ComboBox ItemsSource="{Binding Path=ComboList, Source={StaticResource ComboList}}" SelectedItem="{Binding Path=Value,Mode=TwoWay,Converter={StaticResource BitFormatter}}" HorizontalContentAlignment="Stretch" Margin="3,0"> </ComboBox> </DataTemplate> <DataTemplate x:Key="ColText"> <TextBox Name="Textbox" Text="{Binding ExposedValue, Mode=TwoWay}" HorizontalContentAlignment="Stretch" IsReadOnly="{Binding Path=MustSelectFromList}" ></TextBox> </DataTemplate> <DataTemplate x:Key="ColDatePicker" > <controls:DatePicker Text="{Binding Path=ExposedValue, Mode=TwoWay,Converter={StaticResource DateTimeConverter}}" HorizontalContentAlignment="Stretch" ></controls:DatePicker> </DataTemplate> <DataTemplate x:Key="ColIntNumericUpdown"> <inputToolkit:NumericUpDown Name="numericUpDown" HorizontalContentAlignment="Stretch" Value="{Binding Path=ExposedValue, Mode=TwoWay}" Maximum="{Binding Path=MaxRange,Converter={StaticResource IntFormatter},ConverterParameter=MaxRange}" Minimum="{Binding Path=MinRange,Converter={StaticResource FloatFormatter},ConverterParameter=MinRange}" IsEditable="{Binding Path=MustSelectFromList,Converter={StaticResource MustSelectFormatter} }" ></inputToolkit:NumericUpDown> </DataTemplate> <DataTemplate x:Key="ColFloatNumericUpdown"> <inputToolkit:NumericUpDown Name="numericUpDown" HorizontalContentAlignment="Stretch" Value="{Binding Path=ExposedValue, Mode=TwoWay}" Maximum="{Binding Path=MaxRange,Converter={StaticResource FloatFormatter},ConverterParameter=MaxRange}" Minimum="{Binding Path=MinRange,Converter={StaticResource FloatFormatter},ConverterParameter=MinRange}" IsEditable="{Binding Path=MustSelectFromList,Converter={StaticResource MustSelectFormatter} }" DecimalPlaces="2" ></inputToolkit:NumericUpDown> </DataTemplate> <DataTemplate x:Key="ColTextBlock"> <TextBlock Name="textBlock" Text="{Binding CodeDescription, Mode=TwoWay}" HorizontalAlignment="Stretch" TextWrapping="Wrap" ScrollViewer.VerticalScrollBarVisibility="Auto"></TextBlock> </DataTemplate>
</UserControl.Resources> <Grid x:Name="LayoutRoot" Background="White"> <controls:TabControl x:Name="tabProperties" Grid.Row="1" Grid.Column="0" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<controls:TabItem Header="Properties">
<igGrid:XamGrid x:Name="reportPropertiesValueGrid" ItemsSource="{Binding PropertyWrapper}" AutoGenerateColumns="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" InitializeRow="reportPropertiesValueGrid_InitializeRow">
<igGrid:XamGrid.Columns> <igGrid:TemplateColumn Key="IsRequired" IsReadOnly="True" Width="SizeToCell" HorizontalContentAlignment="Center" > <igGrid:TemplateColumn.HeaderTemplate> <DataTemplate> <TextBlock Text=""/> </DataTemplate> </igGrid:TemplateColumn.HeaderTemplate> <igGrid:TemplateColumn.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Path=IsRequired,Converter={StaticResource MandatoryFormatter}}" Foreground="Red" ></TextBlock> </DataTemplate> </igGrid:TemplateColumn.ItemTemplate> </igGrid:TemplateColumn> <igGrid:TemplateColumn Key="Name" IsReadOnly="True" Width="Auto" MinimumWidth="250"> <igGrid:TemplateColumn.HeaderTemplate> <DataTemplate> <TextBlock Text="Name"/> </DataTemplate> </igGrid:TemplateColumn.HeaderTemplate> <igGrid:TemplateColumn.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Name,Mode=TwoWay}"></TextBlock> </DataTemplate> </igGrid:TemplateColumn.ItemTemplate> </igGrid:TemplateColumn> </igGrid:XamGrid.Columns> <igGrid:XamGrid.EditingSettings> <igGrid:EditingSettings AllowEditing="Cell" IsMouseActionEditingEnabled="SingleClick" IsOnCellActiveEditingEnabled="True"> </igGrid:EditingSettings> </igGrid:XamGrid.EditingSettings> <igGrid:XamGrid.RowSelectorSettings> <igGrid:RowSelectorSettings EnableRowNumbering="False" Visibility="Collapsed"></igGrid:RowSelectorSettings> </igGrid:XamGrid.RowSelectorSettings> <igGrid:XamGrid.ColumnResizingSettings> <igGrid:ColumnResizingSettings AllowColumnResizing="Indicator"></igGrid:ColumnResizingSettings> </igGrid:XamGrid.ColumnResizingSettings> <igGrid:XamGrid.SelectionSettings> <igGrid:SelectionSettings CellClickAction="SelectRow" RowSelection="Single"></igGrid:SelectionSettings> </igGrid:XamGrid.SelectionSettings>
</igGrid:XamGrid> </controls:TabItem>
<controls:TabItem Header="Raw Properties"> <igGrid:XamGrid x:Name="rawPropertiesGrid" ItemsSource="{Binding PropertyWrapper}" AutoGenerateColumns="true" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
<controls:TabItem Header="Other" >
<igGrid:XamGrid x:Name="otherGrid" ItemsSource="{Binding Employees}" AutoGenerateColumns="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" > <igGrid:XamGrid.Columns>
<igGrid:TextColumn Key="FirstName" HeaderText="First Name" Width="50*" /> <igGrid:TextColumn Key="LastName" HeaderText="Last Name" Width="50*" />
</igGrid:XamGrid.Columns>
<igGrid:XamGrid.RowSelectorSettings> <igGrid:RowSelectorSettings Visibility="Collapsed" /> </igGrid:XamGrid.RowSelectorSettings>
<igGrid:XamGrid.SortingSettings> <igGrid:SortingSettings AllowSorting="False" /> </igGrid:XamGrid.SortingSettings>
</igGrid:XamGrid>
</controls:TabItem>
</controls:TabControl>
</Grid></UserControl>
View.cs
using System.Windows;using System.Windows.Controls;using Infragistics.Controls.Grids;
namespace PropertiesTest{ public partial class MainPage : UserControl { private TemplateColumn _TempCol = new TemplateColumn(); private TemplateColumn _TempDescription = new TemplateColumn();
public MainPage() { InitializeComponent(); Model = new PropertiesPMod();
_TempCol.Key = "ExposedValue"; _TempCol.Width = ColumnWidth.Auto; _TempCol.HeaderText = "Value"; _TempCol.MinimumWidth = 130; _TempCol.AllowEditingValidation = true;
_TempDescription.Key = "Description"; _TempDescription.HeaderText = "Description"; _TempDescription.Width = ColumnWidth.Auto; _TempDescription.MinimumWidth = 150; _TempDescription.ItemTemplate = Resources["ColTextBlock"] as DataTemplate;
if (!reportPropertiesValueGrid.Columns.Contains(_TempCol)) reportPropertiesValueGrid.Columns.Add(_TempCol); if (!reportPropertiesValueGrid.Columns.Contains(_TempDescription)) reportPropertiesValueGrid.Columns.Add(_TempDescription);
TemplateColumn templateColumn = (TemplateColumn)reportPropertiesValueGrid.Columns[1]; templateColumn.MinimumWidth = 130;
reportPropertiesValueGrid.UpdateLayout();
public PropertiesPMod Model { get { return this.DataContext as PropertiesPMod; } set { this.DataContext = value; } }
private void reportPropertiesValueGrid_InitializeRow(object sender, InitializeRowEventArgs e) { PropertyWrapper data = (PropertyWrapper)e.Row.Data; if (data == null) return;
//Template should be ColMustSelectText irrespective of the DataType when MustSelectFromList is true if (data.MustSelectFromList && data.SqlDataType.ToLower() != "bit") { _TempCol.ItemTemplate = Resources["ColMustSelectText"] as DataTemplate; } else { switch (data.SqlDataType.ToLower()) { case "date": { _TempCol.ItemTemplate = Resources["ColDatePicker"] as DataTemplate; break; } case "varchar": { _TempCol.ItemTemplate = Resources["ColText"] as DataTemplate; break; } case "float": { _TempCol.ItemTemplate = Resources["ColFloatNumericUpdown"] as DataTemplate; break; } case "int": { _TempCol.ItemTemplate = Resources["ColIntNumericUpdown"] as DataTemplate; break; } case "char": { _TempCol.ItemTemplate = Resources["ColText"] as DataTemplate; break; } case "bit": { _TempCol.ItemTemplate = Resources["Colcombobox"] as DataTemplate; break; } } } } }}
Hi,
I"m not sure how this was working in 10.2.
However, InitRow is only raised the first time a row comes into view. So, as soon as that row goes out of view the control that was used for it will be recycled and attached to another row. If that row was already init'd then it will have a "stale" control in it.
Perhaps, the version of 10.2 had an older version of recycling, which was less efficient and that's why it appeared to work.
However, your better bet would probably be to have some kind of ValueConverter in your DataTemplate, that based on a value of the row, would toggle the visibility of your resources for you.
-SteveZ
Just want to add one more thing it works fine with Xamgrid.v10.2