WPF Data Binding and Data from SQL DataTable - need some ideas - wpf

i have a lot of some WPF windows. On them i write some code, which binds UI controls and data, something like this:
public class AddressWindow
{
public string AddressID { get; set; }
public string Addr1 { get; set; }
public string Addr2 { get; set; }
public string ZIP { get; set; }
public string City { get; set; }
public string Mobile { get; set; }
public string FAX { get; set; }
public string Country { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public bool IsSystem { get; set; }
public bool Enabled { get; set; }
}
private void BindInCode()
{
var address = new AddressWindow
{
// AddressID = "110",
// Addr1 = "Kaunas",
// Addr2 = "Jonavos",
// ZIP = "8987",
// City = "miestas",
// Mobile = "869985868",
// FAX = "87998",
// Country = "Lithuania",
// Email = "emailas#ree.lt",
// Phone = "37598288",
// IsSystem = true,
// Enabled = false
};
Binding binding = new Binding();
binding.Source = address;
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
binding.Path = new PropertyPath("AddressID");
this.db_AddressID.SetBinding(TextEdit.TextProperty, binding);
binding = new Binding();
binding.Source = address;
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
binding.Path = new PropertyPath("Addr1");
this.db_Addr1.SetBinding(TextEdit.TextProperty, binding);
...............
}
Now I want to create some universal simple engine, to fill Data values(assign values from DataTable to my class properties). Does anyone knows some way how to do that..? In example is there some way to assign values by names of properties. Lets say my property names equals to names of Columns from dataRow. Is its possible in wpf to do something like that, or not, should i assign values in every window manually?

Personally I've recourse to code generation to do the job, but you can use to Jimmy Bogard's AutoMapper, which does pretty much what you're talking about. It is on CodePlex and GoogleCode.

Related

Bindingsource on combobox

I create the small winform to do test bing
Existing class as below
public class Book
{
public int Id { get; set; }
public string BookName { get; set; }
public int? CatalogID { get; set; }
}
public class BookCatalog
{
public int Id { get; set; }
public string CataLogName { get; set; }
}
and I create the form with two control, Textbox and Combobox
which initial as below
private Book BookRecord;
private List<BookCatalog> bookCatalogs;
private BindingSource BindingSource = new BindingSource();
public frmBook()
{
InitializeComponent();
// I have initial one bookrecord and multi bookCatalogs here
cbBookCatagories.DisplayMember = "CataLogName";
cbBookCatagories.ValueMember = "Id";
cbBookCatagories.DataSource = bookCatalogs;
BindingSource.DataSource = BookRecord;
txtBoxBookName.DataBindings.Add("Text", BindingSource, "BookName");
cbBookCatagories.DataBindings.Add("SelectedValue", BindingSource, "CatalogID");
}
The first run is fine, but when I want to clear BookRecord as below code
BookRecord.Id = 0;
BookRecord.BookName = null;
BookRecord.AuthorName = null;
BookRecord.CatalogID = null;
BindingSource.ResetBindings(false);
My combobox cannot change value and always point to zeroindex
can anyone guide me how to handle BindingSource() on comboxbox ?
Thank you

Pass parameters to report Devexpress

Please tell me. Created 2 classes (Data Model)
public class User
{
public int UserID { get; set; }
public string UserName { get; set; }
public string Department { get; set; }
public int Office { get; set; }
public string Position { get; set; }
public string Phone { get; set; }
public float Mobile { get; set; }
public string EMail { get; set; }
public string Login { get; set; }
public int idArm { get; set; }
}
and
public class arm
{
public int id { get; set; }
public string name { get; set; }
public string Detalis { get; set; }
}
I installed 2 GridControlls on the form
And through DataSet showed data
string connectionString = ConfigurationManager.ConnectionStrings["connectionSIPiT"].ConnectionString;
string command = "SELECT * FROM Users";
string command2 = "SELECT * FROM arm";
sqlConnection = new SqlConnection(connectionString);
SqlDataAdapter adapter = new SqlDataAdapter(command2, sqlConnection);
SqlDataAdapter adapter1 = new SqlDataAdapter(command, sqlConnection);
DataSet dataset1 = new DataSet();
adapter.Fill(dataset1, "arm");
adapter1.Fill(dataset1, "Users");
DataColumn keyColumn = dataset1.Tables[0].Columns[0];
DataColumn foreignKeyColumn = dataset1.Tables[1].Columns[9];
dataset1.Relations.Add("armUsers", keyColumn, foreignKeyColumn);
armBindingSource.DataSource = dataset1;
armBindingSource.DataMember = "arm";
userBindingSource.DataSource = armBindingSource;
userBindingSource.DataMember = "armUsers";
gridControl1.DataSource = userBindingSource;
gridControl2.DataSource = armBindingSource;
How do I select a row in the main table GridControll. Send report data. Or pass the id of the main table to build the report? Can anyone come across such a task?
Make sure that the Modifiers property for the report parameter is set to Public or Internal
Use the GridView.GetRowCellValue method to get the ID column value of the focused record
The following assumes that you have a report called MyReport and it has a parameter called MyParameter.
var id = Convert.ToInt32(gridView1.GetRowCellValue(gridView1.FocusedRowHandle, gridView1.Columns["UserID"]));
var rpt = new MyNewReport();
rpt.MyParameter.Value = id; //Make sure the MyParameter's Modifiers property is set to Public or Internal.

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.

Powerpacks DataRepeater Control - Image not getting loaded in picture box

I have a winform powerpacks datareapter control having a picture box. This is the code snippet from the classes.
DisplaySystemUsersControl.Designer.cs
this.picBoxUserImage.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.picBoxUserImage.DataBindings.Add(new System.Windows.Forms.Binding("Image", this.UserBindingSource, "User_Image", true));
this.picBoxUserImage.Location = new System.Drawing.Point(3, 3);
this.picBoxUserImage.Name = "picBoxUserImage";
this.picBoxUserImage.Size = new System.Drawing.Size(100, 93);
this.picBoxUserImage.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.picBoxUserImage.TabIndex = 0;
this.picBoxUserImage.TabStop = false;
this.picBoxUserImage.Click += new System.EventHandler(this.picBoxUserImage_Click);
DisplaySystemUsersControl.cs
public DisplaySystemUsersControl()
{
InitializeComponent();
this.dataRepeaterAccounts.DataSource = this.UserBindingSource;
LoadAccountData();
}
private void LoadAccountData()
{
SystemUserBusinessClass oSystemUserBusinessClass = new SystemUserBusinessClass();
List<SystemUserEntity_Only_For_UI_Binding> obj = oSystemUserBusinessClass.GetSystemUsersForUI();
BindingSource tempUserBindingSource = (BindingSource)dataRepeaterAccounts.DataSource;
obj.ForEach(oSystemUserEntity_Only_For_UI_Binding => tempUserBindingSource.Add(oSystemUserEntity_Only_For_UI_Binding));
}
SystemUserEntity_Only_For_UI_Binding.cs
public class SystemUserEntity_Only_For_UI_Binding
{
public string User_Id { get; set; }
public string User_Name { get; set; }
public byte[] User_Image { get; set; }
}
User ID and User name is getting loaded. But Image is not getting loaded. SystemUserEntity_Only_For_UI_Binding.User_Image() is holding the image byte array.
Can anybody please tell me what is going wrong?
Your class should look something like this:
public class SystemUserEntity_Only_For_UI_Binding
{
public string User_Id { get; set; }
public string User_Name { get; set; }
public Image User_Image { get; set; }
}
The byte array needs to be translated into an image somewhere in your code:
using (MemoryStream ms = new MemoryStream(imgBytes)) {
this.User_Image = Image.FromStream(ms);
}
public void BindRepeater (DataSet dsObj)
{
pictureBox1.DataBindings.Clear();
pictureBox1.DataBindings.Add("ImageLocation", dt, "Photo");
dataRepeater1.DataSource = dsObj;
}

JSON.NET Array Serialization in C#.NET

I am trying to create a class for serializing and deserializing arrays. The class I have created, appears to be working for deserializing, but when I try to serialize the array, I am having issues. I am a fairly new C# developer and I am sure I have left an important piece out of my code, I just am not sure what.
Below is a copy of the class I created:
namespace PinnacleCartFormAPI
{
class clsGetCustomersResponse
{
public Customer Customer = new Customer();//{ get; set; }
}
public class Customer
{
public Int32 UserId;
public string UserName;
public CustBilling Billing = new CustBilling();
public AddressBook[] AddressBook;// AddressBook = new AddressBook();
}
public class CustBilling
{
public string FullName, FirstName, LastName, Email, Company, Phone;
public CustAddress Address = new CustAddress();
}
public class CustAddress
{
public string Name, Street1, Street2, City, State, Zip, Country;
}
public class AddressBook
{
public string Name, Street1, Street2, City, State, Zip, Country;
}
}
As you can see, the AddressBook class needs to be an Array. I believe my issue is related to the fact that I am not initiating the AddressBook class properly as an array.
Below, is a copy of the calling code that adds values to the different elements of the class:
clsGetCustomersResponse GetCustomersResp = new clsGetCustomersResponse();
GetCustomersResp.Customer.UserId = 123456;
GetCustomersResp.Customer.UserName = "Username";
GetCustomersResp.Customer.Billing.FullName = "Full Name";
GetCustomersResp.Customer.Billing.FirstName = "First Name";
GetCustomersResp.Customer.Billing.LastName = "Last Name";
GetCustomersResp.Customer.Billing.Email = "email#domain.com";
GetCustomersResp.Customer.Billing.Phone = "7778889999";
GetCustomersResp.Customer.Billing.Address.Name = "Address Name";
GetCustomersResp.Customer.Billing.Address.Street1 = "Address Street 1";
GetCustomersResp.Customer.Billing.Address.Street2 = "";
GetCustomersResp.Customer.Billing.Address.City = "Address City";
GetCustomersResp.Customer.Billing.Address.State = "Address State";
GetCustomersResp.Customer.Billing.Address.Zip = "Address Zip";
GetCustomersResp.Customer.Billing.Address.Country = "Address Country";
GetCustomersResp.Customer.AddressBook[0].Name = "Address Name";
GetCustomersResp.Customer.AddressBook[0].Street1 = "Address Street 1";
GetCustomersResp.Customer.AddressBook[0].Street2 = "";
GetCustomersResp.Customer.AddressBook[0].City = "Address City";
GetCustomersResp.Customer.AddressBook[0].State = "Address State";
GetCustomersResp.Customer.AddressBook[0].Zip = "Address Zip";
GetCustomersResp.Customer.AddressBook[0].Country = "Address Country";
As soon as I hit the bolded lines, I receive the following error:
"Object reference not set to an instance of an object"
Again, I believe this is a result of me not properly initializing the AddressBook portion of the code. However, I am not certain how to do that with the array.
Can you please provide me with some direction on this?
Thanks,
Zach
(Just to be clear, this doesn't really have anything to do with JSON.)
Yes, you have to initialize an array before you start putting values in it. Unfortunately arrays are of a fixed size - you can't change the size (e.g. by adding an element) after they've been created. I would suggest using a List<AddressBook> instead of an array. Then you can use:
// This initialization could be in the type itself
GetCustomersResp.Customer.AddressBook = new List<AddressBook>();
AddressBook address = new AddressBook();
address.Name = "Address Name";
address.Street1 = "Address Street 1";
// etc
GetCustomersResp.Customer.AddressBook.Add(address);
I'd also be tempted to rename the AddressBook type - it's just a single address, not a whole address book. The property within Customer could still be called AddressBook, as an address book is a collection of addresses.
Try this (for 10 address books):
GetCustomersResp.Customer.AddressBook = new AddressBook[10];
You need to instantiate your array before you try to assign elements in it
Agreed with Jon's answer - I didn't spend a ton of time on it, but maybe you'll find this refactored set of classes useful:
namespace Pinnacle.Cart.Customers
{
public class RetrieveResponse
{
public RetrieveResponse() { }
public RetrieveResponse(Customer customer) {
Customer = customer;
}
public Customer Customer { get; set; }
}
public class Customer
{
public Customer() {
Billing = new BillingInfo();
AddressBook = new List<AddressBookEntry>();
}
public Int UserId { get; set; }
public String UserName { get; set; }
public BillingInfo Billing { get; set; }
public List<AddressBookEntry> AddressBook { get; set; }
public class BillingInfo
{
public BillingInfo() { Address = new Address(); }
public String FullName { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
public String Email { get; set; }
public String Company { get; set; }
public String Phone { get; set; }
public Address Address { get; set; }
}
}
public class Address
{
public String Street1 { get; set; }
public String Street2 { get; set; }
public String City { get; set; }
public String State { get; set; }
public String Zip { get; set; }
public String Country { get; set; }
}
public class AddressBookEntry : Address
{
public string Name { get; set; }
}
}

Resources