I am trying to create a dynamic control based in MVC,
I got a solution to implement.. it working fine..
with this code
public class DynamicControlViewModel
{
public ControlViewModel[] Controls { get; set; }
}
public abstract class ControlViewModel
{
public abstract string Type { get; }
public bool Visible { get; set; }
public string Label { get; set; }
public string Name { get; set; }
}
public class TextBoxViewModel : ControlViewModel
{
public override string Type
{
get { return "textbox"; }
}
public string Value { get; set; }
}
public class CheckBoxViewModel : ControlViewModel
{
public override string Type
{
get { return "checkbox"; }
}
public bool Value { get; set; }
}
public class DropDownListViewModel : TextBoxViewModel
{
public override string Type
{
get { return "ddl"; }
}
public SelectList Values { get; set; }
}
This is the way i am calling the object
public ActionResult Index()
{
return View(GetControls1());
}
public DynamicControlViewModel GetControls1()
{
var model1 = new DynamicControlViewModel
{
Controls = new ControlViewModel[] {
new DropDownListViewModel{Visible = true,Label = "drop label",Name = "DropDown1",Values = new SelectList(new[]{new { Value = "1", Text = "text 1" },new { Value = "2", Text = "text 2" },new { Value = "3", Text = "text 3" },}, "Value", "Text", "2")},
new TextBoxViewModel { Visible = true, Label = "label 1", Name = "TextBox1", Value = "value of textbox" },
new CheckBoxViewModel { Visible = true, Label = "CheckBox label 1", Name = "CheckBox1", Value = true},
new TextBoxViewModel { Visible = true, Label = "label 2", Name = "TextBox2", Value = "value of textbox" }}
};
return model1;
}
Here,
I need to use for loop to create the dynamic control..
here is my code, getting error
public DynamicControlViewModel GetControls()
{
var model = new DynamicControlViewModel { };
var Controls1 = new ControlViewModel[] { };
var s = model.Controls;
//int i=0;
//for loop start
Controls1[0] = new TextBoxViewModel { Visible = true, Label = "label 2", Name = "TextBox2", Value = "value of textbox" };
Controls1[1] = new TextBoxViewModel { Visible = true, Label = "label 3", Name = "TextBox3", Value = "value of textbox" };
Controls1[2] = new CheckBoxViewModel { Visible = true, Label = "CheckBox label 1", Name = "CheckBox1", Value = true },
Controls1[3] = new DropDownListViewModel { Visible = true, Label = "drop label", Name = "DropDown1", Values = new SelectList(new[] { new { Value = "1", Text = "text 1" }, new { Value = "2", Text = "text 2" }, new { Value = "3", Text = "text 3" }, }, "Value", "Text", "2") },
//loop end
var model1 = new DynamicControlViewModel
{
Controls = Controls1
};
return model1;
}
The problem is that you first define an array of size 0 (i.e. with 0 cells to hold values):
var Controls1 = new ControlViewModel[] { }; // array with length 0
Afterwards you try to assign to the first, second, third and fourth cell of the array, which do not exist. Therefore you get the error.
So you should either use a List<ControlViewModel> or initialize an array of the correct length:
var Controls1 = new ControlViewModel[4];
Related
I have a flat object, and it looks like as below
public class Test
{
public string Name {get; set;}
public string Number {get; set;}
public string Description {get; set;}
public string Name1 {get; set;}
public string Name2 {get; set;}
}
and I have the data looks like as below
List<Test> tests = new List<Test>
{
new Test{ Name = "nameA", Number=8, Description="description", Name1 = "test 1", Name2="test name1" },
new Test{ Name = "nameB", Number=3, Description="description2", Name1 = "test 2", Name2="test name2" },
new Test{ Name = "nameC", Number=4, Description="description3", Name1 = "test 3", Name2="test name3" },
};
and I am trying to form an object list that looks like below
I am using the below logic to form a list object but failed to add all objects to that,
List<dynamic> testList = new();
int rowIndex = 1;
foreach (var testDt in tests)
{
dynamic testData = new ExpandoObject();
if (rowIndex % 2 != 0)
{
testData.Name = testDt.Name;
testData.Description = testDt.Description;
testData.Number = testDt.Number;
}
else
{
testData.Name1 = testDt.Name1;
testData.Name2 = testDt.Name2;
}
testList.Add(testData);
rowIndex++;
}
But this logic is not adding all items to the list if the list has more items and could anyone please let me know where I am wrong with the above code.
Many thanks in advance!!!
Here you go:
List<Test> tests = new List<Test>
{
new Test{ Name = "nameA", Number = 8, Description = "description", Name1 = "test 1", Name2 = "test name1" },
new Test{ Name = "nameB", Number = 3, Description = "description2", Name1 = "test 2", Name2 = "test name2" },
new Test{ Name = "nameC", Number = 4, Description = "description3", Name1 = "test 3", Name2 = "test name3" },
};
var results =
from t in tests
from r in new []
{
new { t.Name, Number = t.Number.ToString(), t.Description, Name1 = "", Name2 = "", },
new { Name = "", Number = "", Description = "", Name1 = t.Name1, t.Name2, },
}
select r;
That gives me:
To use a regular foreach loop this would work:
public class Output
{
public string Name { get; set; }
public string Number { get; set; }
public string Description { get; set; }
public string Name1 { get; set; }
public string Name2 { get; set; }
}
var results = new List<Output>();
foreach (var t in tests)
{
results.Add(new Output() { Name = t.Name, Number = t.Number.ToString(), Description = t.Description, Name1 = "", Name2 = "", });
results.Add(new Output() { Name = "", Number = "", Description = "", Name1 = t.Name1, Name2 = t.Name2, });
}
I've created a new class rather than use dynamic, as dynamic generally creates more problems than it solves, IMO. I avoid it where possible.
And finally, the equivalent using LINQ's method syntax:
results =
tests
.SelectMany(t => new []
{
new Output() { Name = t.Name, Number = t.Number.ToString(), Description = t.Description, Name1 = "", Name2 = "", },
new Output() { Name = "", Number = "", Description = "", Name1 = t.Name1, Name2 = t.Name2, },
})
.ToList();
The problem is that you are adding only 1 item to the list for each iterate, however, what you need is to add 2 instead to be able to get the expected result.
You can simply do that as follows.
foreach (var testDt in tests)
{
dynamic testData1 = new ExpandoObject();
testData1.Name = testDt.Name;
testData1.Description = testDt.Description;
testData1.Number = testDt.Number;
testList.Add(testData1);
dynamic testData2 = new ExpandoObject();
testData2.Name1 = testDt.Name1;
testData2.Name2 = testDt.Name2;
testList.Add(testData2);
}
I have following class
public class ComboData
{
public int Id { get; set;}
public string Value { get; set;}
public string description { get; set;}
}
I'm binding data to combo box like following
List<ComboData> ListData = new List<ComboData>();
ListData.Add(new ComboData { Id = "1", Value = "One" });
ListData.Add(new ComboData { Id = "2", Value = "Two" });
ListData.Add(new ComboData { Id = "3", Value = "Three" });
ListData.Add(new ComboData { Id = "4", Value = "Four" });
ListData.Add(new ComboData { Id = "5", Value = "Five" });
cbotest.ItemsSource = ListData;
cbotest.DisplayMemberPath = "Value";
cbotest.SelectedValuePath = "Id";
cbotest.SelectedValue = "2";
now I changed my code to get above hard coded values from following Entity Framework GetAll method
public class DAL
{
Dbcontext db = new Dbcontext();
public List<ComboData> GetAll()
{
var sp = db.ComboDatas.ToList();
return sp;
}
}
How can I bind this values to above cbotest.ItemsSource directly with Id and Value ?
It will be, just assign the function to the ItemsSource which will return a List of ComboData
cbotest.ItemsSource = GetAll();
cbotest.DisplayMemberPath = "Value";
cbotest.SelectedValuePath = "Id";
cbotest.SelectedValue = "2";
I have a problem which i'd divide in two steps:
Problem1.
Form an observable collection of strings and bind it to a datagrid
ObservableCollection<string[]> octest = new ObservableCollection<string[]>();
var el = new string[6] {"1","2","3", "4", "5", "6" };
octest.Add(el);
octest.Add(el);
octest.Add(el);
dtgResults.ItemsSource = octest;
the problem is that the binding results in the image below:
Problem 2
The same but now with an array of strings but with mixed elements (e.g. 3 strings and 3 doubles)
thank you
--EDIT-- for CBreeze
I have done that:
ObservableCollection<TestModel> t = new ObservableCollection<TestModel>();
var t1 = new TestModel();
t.Add(t1);
t.Add(t1);
t.Add(t1);
dtgResults.ItemsSource = t;
}
}
public class TestModel
{
public TestModel()
{
TestDouble1 = new string[3];
TestDouble1[0] = "A";
TestDouble1[1] = "B";
TestDouble1[2] = "C";
}
public string[] TestDouble1 { get; set; }
}
and the result is:
from
programmatically add column & rows to WPF Datagrid
you can do that:
string[] columnLabels = new string[] { "Column 0", "Column 1", "Column 2", "Column 3", "Column 4", "Column 5" };
foreach (string label in columnLabels)
{
DataGridTextColumn column = new DataGridTextColumn();
column.Header = label;
column.Binding = new Binding(label.Replace(' ', '_'));
dtgResults.Columns.Add(column);
}
int[] ivalues = new int[] { 0, 1, 2, 3 };
string[] svalues = new string[] { "A", "B", "C", "D" };
dynamic row = new ExpandoObject();
for (int i = 0; i < 6; i++)
{
switch (i)
{
case 0:
case 1:
case 2:
string str = columnLabels[i].Replace(' ', '_');
((IDictionary<String, Object>)row)[str] = ivalues[i];
break;
case 3:
case 4:
case 5:
string str2 = columnLabels[i].Replace(' ', '_');
((IDictionary<String, Object>)row)[str2] = svalues[i - 3];
break;
}
}
dtgResults.Items.Add(row);
Bind your ObservableCollection to a Model;
ObservableCollection<TestModel> octest = new ObservableCollection<TestModel>();
Create your TestModel;
public class TestModel
{
public double TestDouble1 { get; set; }
public double TestDouble2 { get; set; }
public double TestDouble3 { get; set; }
public string TestString1 { get; set; }
public string TestString2 { get; set; }
public string TestString3 { get; set; }
}
You then need to actually create a TestModel....
TestModel newTestModel = new TestModel();
Add new values to TestModel.....
newTestModel.TestString1 = "Hello"
newTestModel.TestString2 = "Hello"
newTestModel.TestString3 = "Hello"
Finally add the new TestModel to the ObservableCollection;
octest.Add(newTestModel);
So im working with this complex anonymous object
var result = new
{
percentage = "hide",
bullets = (string)null,
item = new [] {
new {
value = 16,
text = "Day",
prefix = (string)null,
label = (string)null
},
new {
value = 41,
text = "Week",
prefix = (string)null,
label = (string)null
},
new {
value = 366,
text = "Month",
prefix = (string)null,
label = (string)null
}
}
};
And I want to convert it into a ViewModel and return it as JSON from a rest API.
What I would like to know is
How do I represent this as a model including the array item entries
How do I then add array items to the array once an instance of the model is created
Does the model need a constructor to initialize the array.
Any help or examples you could provide would be great.
Create a class with the structure:
public class Result
{
public Result()
{
// initialize collection
Items = new List<Item>();
}
public string Percentage { get; set; }
public string Bullets { get; set; }
public IList<Item> Items { get; set; }
}
public class Item
{
public int Value { get; set; }
public string Text { get; set; }
public string Prefix { get; set; }
public string Label { get; set; }
}
Then change your code to this:
var result = new Result
{
Percentage = "hide",
Bullets = (string)null,
Items = {
new Item {
Value = 16,
Text = "Day",
Prefix = (string)null,
Label = (string)null
},
new Item {
Value = 41,
Text = "Week",
Prefix = (string)null,
Label = (string)null
},
new Item {
Value = 366,
Text = "Month",
Prefix = (string)null,
Label = (string)null
}
}
};
Addressed above with the structure.
Add to collection as follows:
result.Items.Add(new Item {
Value = 367,
Text = "Month",
Prefix = (string)null,
Label = (string)null
});
I would initialize the collection in the constructor as above.
To return the json from your controller action add the following:
return Json(result, JsonRequestBehavior.AllowGet);
My question is pretty similar for this
Fill RadGridView dynamically
but i dont want to create datatable
This is grid view
GridView = new RadGridView
{
AutoSizeRows = true,
BeginEditMode = RadGridViewBeginEditMode.BeginEditProgrammatically,
Location = new Point(0, 130),
Name = "GridView",
ShowRowErrors = false,
Size = new Size(390, 100),
TabIndex = 0,
Visible = false
};
This method creates columns in runtime
private List<GridViewTextBoxColumn> InitializeColumns()
{
var result = new List<GridViewTextBoxColumn>();
{
var columnId = new GridViewTextBoxColumn
{
Name = "RecordID",
HeaderText = "ID",
FieldName = "RecordID",
MaxLength = 50,
Width = 50,
DataType = typeof(int)
};
result.Add(columnId);
}
{
var columnInformation = new GridViewTextBoxColumn
{
Name = "RecordInformation",
HeaderText = "Information",
FieldName = "RecordInformation",
MaxLength = 50,
Width = 250,
DataType = typeof(string)
};
result.Add(columnInformation);
}
{
var columnRowType = new GridViewTextBoxColumn
{
Name = "RecordType",
HeaderText = "Type",
FieldName = "RecordType",
MaxLength = 50,
Width = 250,
DataType = typeof(string)
};
result.Add(columnRowType);
}
return result;
}
This class is for grid row
internal class OrderTripChangedAlertItem
{
public int RecordID { get; set; }
public string RecordInformation { get; set; }
public string RecordType { get; set; }
public OrderTripChangedAlertItem(int recordID, string recordInformation, string recordType)
{
RecordID = recordID;
RecordInformation = recordInformation;
RecordType = recordType;
}
}
So i bind the List to grid view. Columns are displayed fine, but not data shown. There must be one record. What i missed ?
Here is the whole code I placed on a Form and this works just fine:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
RadGridView GridView = new RadGridView
{
AutoSizeRows = true,
BeginEditMode = RadGridViewBeginEditMode.BeginEditProgrammatically,
Location = new Point(0, 130),
Name = "GridView",
ShowRowErrors = false,
Size = new Size(390, 100),
TabIndex = 0,
//Visible = false,
Parent = this
};
GridView.Columns.AddRange(InitializeColumns().ToArray());
List<OrderTripChangedAlertItem> list = new List<OrderTripChangedAlertItem>();
OrderTripChangedAlertItem item = new OrderTripChangedAlertItem(0, "some info", "some type");
list.Add(item);
GridView.DataSource = list;
}
private List<GridViewTextBoxColumn> InitializeColumns()
{
var result = new List<GridViewTextBoxColumn>();
{
var columnId = new GridViewTextBoxColumn
{
Name = "RecordID",
HeaderText = "ID",
FieldName = "RecordID",
MaxLength = 50,
Width = 50,
DataType = typeof(int)
};
result.Add(columnId);
}
{
var columnInformation = new GridViewTextBoxColumn
{
Name = "RecordInformation",
HeaderText = "Information",
FieldName = "RecordInformation",
MaxLength = 50,
Width = 250,
DataType = typeof(string)
};
result.Add(columnInformation);
}
{
var columnRowType = new GridViewTextBoxColumn
{
Name = "RecordType",
HeaderText = "Type",
FieldName = "RecordType",
MaxLength = 50,
Width = 250,
DataType = typeof(string)
};
result.Add(columnRowType);
}
return result;
}
internal class OrderTripChangedAlertItem
{
public int RecordID { get; set; }
public string RecordInformation { get; set; }
public string RecordType { get; set; }
public OrderTripChangedAlertItem(int recordID, string recordInformation, string recordType)
{
RecordID = recordID;
RecordInformation = recordInformation;
RecordType = recordType;
}
}