Saving a collection of custom objects in application settings - wpf

I followed Trouble saving a collection of objects in Application Settings to save my ObservableCollection of custom objects which is bound to a DataGrid in the application settings, but the data is not stored in user.config like the other settings.
Can somebody help me with this?
Thank you!
My custom classes:
[Serializable()]
public class ActuatorParameter
{
public ActuatorParameter()
{}
public string caption { get; set; }
public int value { get; set; }
public IntRange range { get; set; }
public int defaultValue { get; set; }
}
and
[Serializable()]
public class IntRange
{
public int Max { get; set; }
public int Min { get; set; }
public IntRange(int min, int max)
{
Max = max;
Min = min;
}
public bool isInRange(int value)
{
if (value < Min || value > Max)
return true;
else
return false;
}
}
Fill collection and save:
Settings.Default.pi_parameters = new ObservableCollection<ActuatorParameter>
{
new ActuatorParameter() { caption = "Velocity", range = new IntRange(1, 100000), defaultValue = 90000},
new ActuatorParameter() { caption = "Acceleration", range = new IntRange(1000, 1200000), defaultValue = 600000},
new ActuatorParameter() { caption = "P-Term", range = new IntRange(150, 350), defaultValue = 320},
new ActuatorParameter() { caption = "I-Term", range = new IntRange(0, 60), defaultValue = 30},
new ActuatorParameter() { caption = "D-Term", range = new IntRange(0, 1200), defaultValue = 500},
new ActuatorParameter() { caption = "I-Limit", range = new IntRange(0, 1000000), defaultValue = 2000}
};
Settings.Default.Save();
My custom setting:
internal sealed partial class Settings
{
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public ObservableCollection<ActuatorParameter> pi_parameters
{
get
{
return ((ObservableCollection<ActuatorParameter>)(this["pi_parameters"]));
}
set
{
this["pi_parameters"] = value;
}
}
}

After long research I finally found out that the IntRange class was missing a standard constructor.
[Serializable()]
public class IntRange
{
public int Max { get; set; }
public int Min { get; set; }
public IntRange()
{}
public IntRange(int min, int max)
{
Max = max;
Min = min;
}
public bool isInRange(int value)
{
if (value < Min || value > Max)
return true;
else
return false;
}
}

Related

How to return a string in the dataGrid.ItemsSource when it contains a ICollection<Continent>

When im displaying my database table it contains a few collections and those dont display in the datagrid. a column is generated but it stays blank. I do not know where to implement this either.
Maybe this will help also to explain what i want to display in the column instead of the ICollection
static void Main(string[] args)
{
using (var db = new Whataboutthisfish())
{
Vis vis = db.Vissen.Find(2);
if(vis != null)
{
if(vis.Continenten != null)
{
string s = "";
if(vis.Continenten.Count() > 1)
{
var continentenLijst = vis.Continenten;
s = continentenLijst.First().Naam;
foreach (Continent c in vis.Continenten)
{
s += ", "+c.Naam;
}
}
else
{
s = vis.Continenten.First().Naam;
}
Console.WriteLine(s);
}
}
}
}
I would like to return 1 string containing each continent's name using a seperator.
Like: "North-America" if there's only 1 continent in the collection
Or: "North-America, South-America" and so on for multiple.
Classes;
[Table("Continenten")]
public partial class Continent
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Continent()
{
Vissen = new HashSet<Vis>();
}
public int Id { get; set; }
[Required]
[StringLength(50)]
public string Naam { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Vis> Vissen { get; set; }
}
}
[Table("Vissen")]
public partial class Vis
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Vis()
{
Continenten = new HashSet<Continent>();
Verbanden = new HashSet<Verband>();
Waterlagen = new HashSet<Waterlaag>();
}
public int Id { get; set; }
[StringLength(200)]
public string Naam { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Continent> Continenten { get; set; }
}
The Xaml for grid:
<DataGrid x:Name="dataGrid" HorizontalAlignment="Left" VerticalAlignment="Top" RenderTransformOrigin="0.833,0.846" Margin="10,10,10,10"/>
In code behind:
using (var db = new Catattafish.Whataboutthisfish())
{
dataGrid.ItemsSource = db.Vissen.ToList();
}

combobox not bound to my value

I know, there are a lot of examples but I'm not getting it to work.
I have a Silverlight Mask where I dynamically add UIElements like Textboxes or ComboBoxes. So far, this is working fine. Now I'm trying to set the ComboBox Selected Item from my database values.
I store the information for generation in my own classes.
public class Metadata
{
public int? MetadataId { get; set; }
public string Name { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public int Column { get; set; }
public MetaDataType MetaDataType { get; set; }
public List<MetadataData> MetadataData { get; set; }
}
public class MetadataData
{
public int MetadataDataId { get; set; }
public int MetadataId { get; set; }
public string Description { get; set; }
}
public partial class MetadataStore
{
public Guid MetadataStoreId { get; set; }
public Guid ObjectId { get; set; }
public Guid ModuleTypeId { get; set; }
public int MetadataSetId { get; set; }
public int? MetadataSetSetId { get; set; }
public int MetadataId { get; set; }
public string Description { get; set; }
public int? RowId { get; set; }
public DataContainer.Profile userProfile { get; set; }
}
My selected value stores the MetadataDataId as a String in my MetadataStore in the field Description. I'm generating the UIElements based on the MetaData class in code-behind like this
switch ((MetaDataDataType)metadata.MetaDataType.MetaDataTypeId)
{
case MetaDataDataType.String:
frmElement = new TextBox() { Name = String.Format("dynCtrl_{0}_{1}", metadata.MetadataId, metadata.Name)
AcceptsReturn = false, Margin = new Thickness(4),
HorizontalAlignment = HorizontalAlignment.Left,
Height = metadata.Height, Width = metadata.Width,
Style = App.Current.Resources["TextBoxStyleFlat"] as Style };
frmElement.SetBinding(TextBox.TextProperty,
new Binding { Mode = BindingMode.TwoWay, Path = new PropertyPath(metadata.Name) });
break;
case MetaDataDataType.SingleSelection:
frmElement = new ComboBox()
{
Name = String.Format("dynCtrl_{0}_{1}", metadata.MetadataId, metadata.Name),
Margin = new Thickness(4),
HorizontalAlignment = HorizontalAlignment.Left,
Style = App.Current.Resources["ComboBoxStyleFlat"] as Style,
ItemsSource = metadata.MetadataData,
DisplayMemberPath = "Description",
//SelectedItem = metadata.Name,
Height = metadata.Height,
Width = metadata.Width
};
frmElement.SetBinding(ComboBox.SelectedValueProperty, new Binding { Mode = BindingMode.TwoWay, Path = new PropertyPath(metadata.Name) });
frmElement.SetBinding(ComboBox.SelectedValuePathProperty, new Binding { Mode = BindingMode.TwoWay, Path = new PropertyPath("MetadataDataId") });
default:
break;
}
I thought I could make it work with an Dictionary<string, object>
var p = new Dictionary<string, object>();
p[mData.Metadata.Name] = Convert.ToInt32(item.Description);
but as it didn't work, I ended up with generating a DataTable and selecting the first element which gets me an Object with my desired dynamic properties.
TempObject.Testprop
TempObject.Nutzen
The DataSourceCreator is used from http://blog.bodurov.com/How-to-Bind-Silverlight-DataGrid-From-IEnumerable-of-IDictionary/.
internal static void generateDataContext(List<MetadataSetMetadata> metadataSetMetadata, List<MetadataStore> metadataStore, ref Grid viewGrid)
{
if (metadataStore != null && metadataStore.Count > 0)
{
dynamic expObj = new ExpandoObject();
var p = new Dictionary<string, object>();
foreach (var item in metadataStore.Where(x => x.MetadataSetSetId == null))
{
var mData = metadataSetMetadata.FirstOrDefault(x => x.Metadata != null && x.Metadata.MetadataId.Equals(item.MetadataId));
switch ((MetaDataDataType)mData.Metadata.MetaDataType.MetaDataTypeId)
{
case MetaDataDataType.String:
case MetaDataDataType.LongString:
p[mData.Metadata.Name] = item.Description;
break;
case MetaDataDataType.SingleSelection:
if (!String.IsNullOrWhiteSpace(item.Description))
{
p[mData.Metadata.Name] = Convert.ToInt32(item.Description);
}
break;
default:
break;
}
}
var emtyRowList = new List<IDictionary>();
emtyRowList.Add(p);
viewGrid.DataContext = DataSourceCreator.ToDataSource(emtyRowList).Cast<object>().FirstOrDefault();
viewGrid.UpdateLayout();
}
}
I set the DataContext for the complete StackPanel. My TextBox shows the correct Text stored in TempObject.Testprop. My ComboBox` only displays its Items Source but its not showing my already selected item, which Id is stored in TempObject.Nutzen.
Any ideas what I'm missing?
UPDATE:
I could make it working, binding the SelectedValue to the MetadataData Object instead of its ID value and setting the SelectedValuePath to the ID property name of MetadataData.
I could make it working, binding the SelectedValue to the MetadataData Object instead of its ID value and setting the SelectedValuePath to the ID property name of MetadataData.

BindingList<> (master) with a composed BindingList<> (child) reference

I have a situation where a BindingList<> represents a collection of POCOs that have sub-collections of similar nature, Here is a sample code of two such POCOs and their respective lists:
The DirectoryTypePoco
public class DirectoryTypePoco : IBasePoco
{
public DirectoryTypePoco()
{
}
public DirectoryTypePoco(Int16 directoryTypeId, String directoryImplementation, String directoryDescription, DirectoryDefinitionPocoList directoryDefinition)
{
DirectoryTypeId = directoryTypeId;
DirectoryImplementation = directoryImplementation;
DirectoryDescription = directoryDescription;
DirectoryDefinition = directoryDefinition;
}
public Int16 DirectoryTypeId { get; set; }
public String DirectoryImplementation { get; set; }
public String DirectoryDescription { get; set; }
public DirectoryDefinitionPocoList DirectoryDefinition { get; set; }
public object GenerateEntity(GenericRepository repository, params object[] parameters)
{
var lastMaxEntityId = repository.GetQuery<DirectoryType>().Select(select => #select.DirectoryTypeId).DefaultIfEmpty().Max();
var newEntity = new DirectoryType
{
DirectoryTypeId = (short)(lastMaxEntityId + 1),
DirectoryImplementation = this.DirectoryImplementation,
DirectoryDescription = this.DirectoryDescription
};
return newEntity;
}
}
And the BindingList<DirectoryTypePoco>:
public class DirectoryTypePocoList : BindingList<DirectoryTypePoco>
{
public DirectoryTypePocoList()
{
using (var repository = new GenericRepository(new PWRDbContext()))
{
var query = repository.GetQuery<DirectoryType>();
foreach (var r in query)
{
Add(new DirectoryTypePoco(r.DirectoryTypeId, r.DirectoryImplementation, r.DirectoryDescription, new DirectoryDefinitionPocoList(r.DirectoryTypeId)));
}
}
}
public DirectoryTypePocoList(short directoryTypeId)
{
using (var repository = new GenericRepository(new PWRDbContext()))
{
var query = repository.GetQuery<DirectoryType>(where => where.DirectoryTypeId == directoryTypeId);
foreach (var r in query)
{
Add(new DirectoryTypePoco(r.DirectoryTypeId, r.DirectoryImplementation, r.DirectoryDescription, new DirectoryDefinitionPocoList(r.DirectoryTypeId)));
}
}
}
}
The second object: DirectoryDefinitionPoco
public class DirectoryDefinitionPoco : IBasePoco
{
public DirectoryDefinitionPoco()
{
}
public DirectoryDefinitionPoco(Int16 directoryTypeId, Byte parameterId, String parameterName, String parameterValidation, Boolean encryptionRequired, PocoChangeType changeType = PocoChangeType.None)
{
DirectoryTypeId = directoryTypeId;
ParameterId = parameterId;
ParameterName = parameterName;
ParameterDescription = parameterName;
ParameterRequired = false;
ParameterValidation = parameterValidation;
EncryptionRequired = encryptionRequired;
}
public Int16 DirectoryTypeId { get; set; }
public Byte ParameterId { get; set; }
public String ParameterName { get; set; }
public String ParameterDescription { get; set; }
public String ParameterValidation { get; set; }
public Boolean ParameterRequired { get; set; }
public Boolean EncryptionRequired { get; set; }
public object GenerateEntity(GenericRepository repository, params object[] parameters)
{
var masterId = (short) parameters[0];
var lastMaxEntityId = repository.GetQuery<DirectoryDefinition>(where => where.DirectoryTypeId == masterId).Select(select => #select.ParameterId).DefaultIfEmpty().Max();
var newEntity = new DirectoryDefinition
{
DirectoryTypeId = (short)parameters[0],
ParameterId = (byte)(lastMaxEntityId + 1),
ParameterName = this.ParameterName,
ParameterDescription = this.ParameterDescription,
ParameterValidation = this.ParameterValidation,
ParameterRequired = this.ParameterRequired,
EncryptionRequired = this.EncryptionRequired
};
return newEntity;
}
}
And BindingList<DirectoryDefinitionPoco>:
public class DirectoryDefinitionPocoList : BindingList<DirectoryDefinitionPoco>
{
public DirectoryDefinitionPocoList(short directoryTypeId)
{
using (var repository = new GenericRepository(new PWRDbContext()))
{
var query = repository.GetQuery<DirectoryDefinition>(where => where.DirectoryTypeId == directoryTypeId);
foreach (var r in query)
{
Add(new DirectoryDefinitionPoco(r.DirectoryTypeId, r.ParameterId, r.ParameterName, r.ParameterValidation, r.EncryptionRequired));
}
}
}
public List<DirectoryDefinition> GetSourceQuery()
{
List<DirectoryDefinition> result;
using (var repository = new GenericRepository(new PWRDbContext()))
{
result = repository.GetQuery<DirectoryDefinition>().ToList();
}
return result;
}
public List<DirectoryDefinition> GetSourceQuery(short directoryTypeId)
{
List<DirectoryDefinition> result;
using (var repository = new GenericRepository(new PWRDbContext()))
{
result = repository.GetQuery<DirectoryDefinition>(where => where.DirectoryTypeId == directoryTypeId).ToList();
}
return result;
}
}
On the form, I load the data into the grid through a BindingSource component. The child rows are added properly and the data is valid.
Here is the issue: I'm able to add new DirectoryTypePoco but when try to add a DirectoryDefinitionPoco, in the code, the the DirectoryDefinitionPocoobject that I get has a zero for it's parent object. In the above picture, the Test5.dll234 is a DirectoryTypePoco with DirectoryTypeId = 8 and all child under it are ok except the new one I create. What am I suppose to do to make sure I have Master-Child relation in this case?
Ok. It seems that there are two thing I should have noticed in my design.
The individual child Poco needs to know the parent Poco through a reference.
The DevExpress Grid has methods that allow for retrieving the attached data to a parent row while in the child view' particular row.
The first part is straightforwards: add a new property in the child poco of parent poco type.
This however, in my case, doesn't solve my issue as when I visually add a new row on the grid, the default constructor is invoked and it takes no parameters and hence the parent poco reference will remain NULL and the Ids (numeric) will be defaulted to 0
The second point helped fix my issue completely. I was able to conjure up an extension method for the XtraGrid's GridView as follows:
public static class DevExpressGridHelper
{
public static IBasePoco GetPocoFromSelectedRow(this BaseView view)
{
return (IBasePoco)view.GetRow(((GridView)view).FocusedRowHandle);
}
public static IBasePoco GetParentPocoFromSelectedRow(this GridView view)
{
if (view.ParentView !=null)
{
// return (IBasePoco)(view.ParentView).GetRow(((GridView)(view.ParentView)).FocusedRowHandle);
return (IBasePoco)((GridView)view.ParentView).GetFocusedRow();
}
return null;
}
}
And used it as follows:
private void GridMain_Level_1_RowUpdated(object sender, RowObjectEventArgs e)
{
var view = sender as GridView;
if (view == null)
{
return;
}
var pocoObject = e.Row as DirectoryDefinitionPoco;
if (pocoObject == null)
{
return;
}
var parentPocoObject = view.GetParentPocoFromSelectedRow();
if (parentPocoObject == null)
{
return;
}
if (view.IsNewItemRow(e.RowHandle))
{
Create(pocoObject, parentPocoObject);
}
else
{
Update(pocoObject);
}
}

DataGrid: How do I programmatically select DataGrid ComboBox items, WITHOUT manipulating the GUI?

I asked this before and have a solution that works:
See Answer by srithar here
Being new to XAML/WPF, that one was my instinctively preferred solution. However, experts keep on telling us: "DO NOT manipulate the GUI! Handle the model instead."
This is the relevant XAML code:
<DataGridTemplateColumn Header=" Top Plate Thickness ">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
ItemsSource="{Binding Gauge, Mode=TwoWay}"
DisplayMemberPath="Thickness"
SelectedItem="{Binding TopPlateThickness, UpdateSourceTrigger=PropertyChanged}" SelectionChanged="ComboBoxLeft_SelectionChanged">
<ComboBox.ItemContainerStyle>
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="IsEnabled" Value="{Binding Enabled}"/>
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
It currently supports the ability to disable menu items. This is the Code Behind:
static List<string> caliber = new List<string> { "0.3750", "0.5000", "0.6250", "0.7500", "1.0000" };
string left = "";
string right = "";
PlateThicknesses(ref left, ref right, rnd);
Selectable top = new Selectable(left);
Selectable bot = new Selectable(right);
GridsModel gm = new GridsModel()
{
OuterDiameter = outerDiameter,
InnerDiameter = innerDiameter,
TopPlateThickness = top,
BottomPlateThickness = bot
};
static void PlateThicknesses(ref string leftComboBoxIndex, ref string rightComboBoxIndex)
{
int a = rnd.Next(7);
int b = rnd.Next(7);
if (a > b)
{
leftComboBoxIndex = caliber[a];
rightComboBoxIndex = caliber[b];
}
else
{
leftComboBoxIndex = caliber[b];
rightComboBoxIndex = caliber[b];
}
}
Model:
public class GridsModel : PropertyChangedBase
{
public string Item { get; set; }
public string Description { get; set; }
private int _Quantity;
public int Quantity
{
get
{
return _Quantity;
}
set
{
if (_Quantity != value)
{
_Quantity = value;
RaisePropertyChanged("Quantity");
}
}
}
private int _QtyOfFound;
public int QtyOfFound
{
get
{
return _QtyOfFound;
}
set
{
if (_QtyOfFound != value)
{
_QtyOfFound = value;
RaisePropertyChanged("QtyOfFound");
}
}
}
public double MaxBoltLoad { get; set; }
public int NumberOfBolts { get; set; }
public double Separation { get; set; }
private double _Length;
public double Length
{
get
{
return _Length;
}
set
{
if (_Length != value)
{
_Length = value;
RaisePropertyChanged("Length");
}
}
}
public double Gamma { get; set; }
public double Beta { get; set; }
public double OuterDiameter { get; set; }
public double InnerDiameter { get; set; }
public List<Selectable> Gauge { get; set; } // Gauche is "Left" in French
private Selectable _TopPlateThickness;
public Selectable TopPlateThickness
{
get
{
return _TopPlateThickness;
}
set
{
if (_TopPlateThickness != value)
{
_TopPlateThickness = value;
RaisePropertyChanged("TopPlateThickness");
}
}
}
public List<Selectable> Caliber { get; set; } // The Right Stuff
private Selectable _BottomPlateThickness;
public Selectable BottomPlateThickness
{
get
{
return _BottomPlateThickness;
}
set
{
if (_BottomPlateThickness != value)
{
_BottomPlateThickness = value;
RaisePropertyChanged("BottomPlateThickness");
}
}
}
public double BoltCircleDiameter { get; set; }
private double _TemplateSetWeight;
public double TemplateSetWeight
{
get
{
return _TemplateSetWeight;
}
set
{
if (_TemplateSetWeight != value)
{
_TemplateSetWeight = value;
RaisePropertyChanged("TemplateSetWeight");
}
}
}
public double AnchorBoltSetWeight { get; set; }
private double _WholeAnchorCageWeight;
public double WholeAnchorCageWeight
{
get
{
return _WholeAnchorCageWeight;
}
set
{
if (_WholeAnchorCageWeight != value)
{
_WholeAnchorCageWeight = value;
RaisePropertyChanged("WholeAnchorCageWeight");
}
}
}
public GridsModel()
{
Gauge = new List<Selectable> { new Selectable("0.3750"),
new Selectable("0.4375"),
new Selectable("0.5000"),
new Selectable("0.6250"),
new Selectable("0.7500"),
new Selectable("0.8650"),
new Selectable("1.0000") };
Caliber = new List<Selectable> { new Selectable("0.3750"),
new Selectable("0.4370"),
new Selectable("0.5000"),
new Selectable("0.6250"),
new Selectable("0.7500"),
new Selectable("0.8650"),
new Selectable("1.0000") };
}
}
Selectable Class:
public class Selectable : PropertyChangedBase
{
private string _Thickness;
public string Thickness
{
get
{
return _Thickness;
}
set
{
if (_Thickness != value)
{
_Thickness = value;
RaisePropertyChanged("Thickness");
}
}
}
private bool _Enabled;
public bool Enabled
{
get
{
return _Enabled;
}
set
{
if (_Enabled != value)
{
_Enabled = value;
RaisePropertyChanged("Enabled");
}
}
}
public Selectable(string thickness)
{
Thickness = thickness;
Enabled = true;
}
}
Using debugging code I can see that the desired properties are actually being assigned the desired values, but the visual UI fails to display them.
TIA

byte array getter setter in C# asp.net

i am taking bytes array from file upload control and saving them in a class object but i am getting exception of stackoverflow infinite loop or recursive like sonmething.
my code is:
public class UploadDetail
{`enter code here`
//public bool IsReady { get; set; }
public string FileSize { get; set; }
//public int UploadedLength { get; set; }
public string FileName { get; set; }
public byte[] FileinBytes;
public byte[] FileBytes
{
get
{
return FileBytes;
}
set
{
FileBytes = value;
}
}
here is my gridview button event where i am setting the objects value:
protected void gvUploadFiles_Clicked(object sender, GridViewCommandEventArgs e)
{
try
{
if (e.CommandName == "doingUpload")
{
int index = Convert.ToInt32(e.CommandArgument);
GridViewRow row = gvUploadFiles.Rows[index];
if (gvUploadFiles.DataKeys[index]["FileName"] != null)
{
currentUpload.FileName = gvUploadFiles.DataKeys[index]["FileName"].ToString();
}
if (gvUploadFiles.DataKeys[index]["FileSize"] != null)
{
currentUpload.FileSize = gvUploadFiles.DataKeys[index]["FileSize"].ToString();
}
if (gvUploadFiles.DataKeys[index]["FileBytes"] == null)
{
currentUpload.FileBytes=(byte[])gvUploadFiles.DataKeys[index]["UploadDetail.FileBytes()"];
//currentUpload.FileBytes(row.FindControl("fileBytes"));
}
You've got an infinite recursion in your getter/setter.
Do you want to write it to FileinBytes?
public byte[] FileBytes
{
get
{
return FileinBytes;
}
set
{
FileinBytes = value;
}
}
An alternative could be to use an auto implemented property:
public byte[] FileBytes { get; set; }

Resources