I am having a wrapper for example.
public class Student{
public string Name{get;set}
public int IDNumber{get;set;}
public ObservableCollection<SubjectWrapper> Subjects{get;set;}
}
public class SubjectWrapper{
public string SubjectName{get;set;}
public bool IsSubjectSelected{get;set;}
}
How can I bind this to Datagrid effectively.There could be any number of subject.All students will have all subject column against there name. Please see the following image.Also I want to follow MVVM pattern(less code behind).
XAML
public partial class MainWindow : Window {
public MainWindow()
{
InitializeComponent();
var student = new Student(){ Name = "Ebin"};
student.Subjects.Add(new SubjectWrapper() { SubjectName="subject1",IsSubjectSelected=true });
student.Subjects.Add(new SubjectWrapper(){ SubjectName = "subject2", IsSubjectSelected = false});
var student2 = new Student() { Name = "Ravi" };
student2.Subjects.Add(new SubjectWrapper() { SubjectName = "subject1", IsSubjectSelected = false });
student2.Subjects.Add(new SubjectWrapper() { SubjectName = "subject2", IsSubjectSelected = true });
var list = new List<Student>();
list.Add(student);
list.Add(student2);
//Name column adding
maingrid.Columns.Add(new DataGridTextColumn(){ Header = "name", Binding = new Binding("Name")});
//Subject columns added dynamically
for (int i = 0; i < list[0].Subjects.Count(); i++) {
var col = new DataGridCheckBoxColumn();
col.Header = list[0].Subjects[i].SubjectName;
col.Binding = new Binding("Subjects[" + i.ToString() + "].IsSubjectSelected");
maingrid.Columns.Add(col);
}
maingrid.ItemsSource = list;
}
}
public class Student
{
public string Name { get; set; }
public int IDNumber { get; set; }
public ObservableCollection<SubjectWrapper> Subjects { get; set; }
public Student()
{
Subjects = new ObservableCollection<WpfApplication1.SubjectWrapper>();
}
}
public class SubjectWrapper {
public string SubjectName { get; set; }
public bool IsSubjectSelected { get; set; }
}
Related
I have three classes
public class FeatureBook
{
public string Id { get; set; }
public String name { get; set; }
public String type { get; set; }
}
public class Feature
{
public String feature_id { get; set; }
public String value { get; set; }
}
public class Human {
public string Id { get; set; }
public bool validated { get; set; }
public List<Feature> features { get; set; }
public override String ToString() => Id;
}
Human has List<Feature>. Feature is linked to FeatureBook by feature_id
And I have DataGridView.
How can I get something like in the picture:
First of all, for such of functionality, i'd use 2 datagridviews with master-detail relationship.
Second of all, if you would like to bind data to single datagridview, you need to convert Feature's rows into columns. Here is complete sample (created with LinqPad):
void Main()
{
//create human list
List<Human> people = new List<Human>()
{
new Human(){Id = "H1", validated =false, features = new List<Feature>()
{
new Feature(){feature_id = "H1F1", value ="Feature 1"},
new Feature(){feature_id = "H1F2", value ="Feature 2"}
}},
new Human(){Id = "H2", validated =false, features = new List<Feature>()
{
new Feature(){feature_id = "H2F1", value ="Feature 1"},
new Feature(){feature_id = "H2F2", value ="Feature 2"},
new Feature(){feature_id = "H2F3", value ="Feature 3"},
new Feature(){feature_id = "H2F4", value ="Feature 4"},
new Feature(){feature_id = "H2F5", value ="Feature 5"}
}}
};
//create datatable
DataTable dt = new DataTable();
//add known columns (related to Human)
dt.Columns.AddRange(new DataColumn[]
{
new DataColumn("Id", typeof(string)),
new DataColumn("validated", typeof(string))
});
//get max. of futures
int fc = people.Select(x=>x.features.Count).Max();
//add columns related to Feature
for(int i=0; i<fc; i++)
dt.Columns.Add(new DataColumn($"Feature {i}"));
//add data to datatable
foreach(Human h in people)
{
//add Human details
DataRow dr = dt.NewRow();
dr["Id"] = h.Id;
dr["validated"] = h.validated;
//add Feature details
for(int i=0; i<h.features.Count; i++)
{
Feature f = h.features[i];
dr[$"Feature {i}"] = f.value;
}
dt.Rows.Add(dr);
}
//datatable is ready to use
//dump its content ;)
dt.Dump();
}
// Define other methods and classes here
public class FeatureBook
{
public string Id { get; set; }
public string name { get; set; }
public string type { get; set; }
}
public class Feature
{
public string feature_id { get; set; }
public string value { get; set; }
}
public class Human
{
public string Id { get; set; }
public bool validated { get; set; }
public List<Feature> features { get; set; }
public override string ToString() => Id;
}
Note: there's few other ways to achieve that, but i wanted to show you the simplest way ;)
Im trying to access and display the value of a dictionary where the dictionary has no real name but is a property of a class.
Currently I have an enum "Roles" with three elements (fighter, rogue, and sorcerer), and:
public class Adventurer
{
public int ID { get; set; }
public string Name { get; set; }
public Roles Role { get; set; }
public List<Skill> Skills { get; set; }
public override string ToString()
{
return $"{ID}" + " - " + $"{Name}" + " - " + $"{Role}";
}
}
and:
public class Skill
{
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public Dictionary<Roles, Skill> LinkedTo { get; set; }
}
and in another class I have:
private void CreateSkills()
{
Skill swordFighting = new Skill() { ID = 1, Name = "Sword fighting"};
Skill stealth = new Skill() { ID = 2, Name = "Stealth"};
Skill magic = new Skill() { ID = 3, Name = "Magic"};
swordFighting.LinkedTo = new Dictionary<Roles, Skill>
{
{ Roles.Fighter, swordFighting }
};
stealth.LinkedTo = new Dictionary<Roles, Skill>
{
{ Roles.Rogue, stealth }
};
magic.LinkedTo = new Dictionary<Roles, Skill>
{
{ Roles.Sorcerer, magic }
};
}
private void DisplaySkills(Adventurer adventurer)
{
adventurer.Skills = adventurer.Role.LinkedTo; // I WOULD LIKE SOMETHING LIKE THIS...
lstAdventurer.ItemsSource = adventurer.Skills;
}
Is there some way of accessing the values (skills) of the adventurer by knowing only the role (fighter/rogue/sorcerer)?
Best,
Dedoj
Would you mean something like this?
for known Roles like Roles.Fighter:
adventurer.Skills = adventurer.Skills
.Select(s => s.LinkedTo.ContainsKey(Roles.Fighter) ? s.LinkedTo[Roles.Fighter] : null)
.Where(s => s != null).ToList();
I have two lists. There are only one field difference. How to fill the lists with each other.
[Serializable()]
public class Lst1
{
public string filed1 { get; set; }
public Int16 filed2 { get; set; }
.
.
.
public Boolean filed100 { get; set; }
}
[Serializable()]
public class Lst2
{
public string filed1 { get; set; }
public Int16 filed2 { get; set; }
.
.
.
public Boolean filed100 { get; set; }
public string filed101 { get; set; }
}
List<Lst1> Lst1_ = new List<Lst1>();
List<Lst2> Lst2_ = new List<Lst2>();
I fill out lists from files.
then,I need to fill out the list two from list one,There are many fields And I do not want to use the foreach loop.
It should be remembered that my previous class was already built and serialized and stored in a file. And now I need to transfer the previous information to the second class structure.
I do not want to use this loop!
foreach (var t in Lst1_)
{
Lst2_.Add(new lst2
{
filed1 = t.filed1,
filed2 = t.filed2,
.
.
.
filed100 = t.filed100,
filed101 = "kk"
}
}
Is this what you want?
class Lst1
{
public string filed1 { get; set; }
public string filed2 { get; set; }
public string filed3 { get; set; }
public string filed4 { get; set; }
public string filed5 { get; set; }
}
class Lst2
{
public string filed1 { get; set; }
public string filed2 { get; set; }
public string filed3 { get; set; }
public string filed4 { get; set; }
public string filed5 { get; set; }
public string filed6 { get; set; }
}
void CopyData()
{
// test data
List<Lst1> Lst1_ = new List<Lst1>()
{
new Lst1()
{
filed1 = "1",
filed2 = "2",
filed3 = "3",
filed4 = "4",
filed5 = "5",
},
new Lst1()
{
filed1 = "6",
filed2 = "7",
filed3 = "8",
filed4 = "9",
filed5 = "10",
},
};
List<Lst2> Lst2_ = new List<Lst2>();
foreach (var item in Lst1_)
{
Type type1 = item.GetType();
PropertyInfo[] properties1 = type1.GetProperties();
var current = new Lst2();
Type type2 = current.GetType();
PropertyInfo[] properties2 = type2.GetProperties();
int k = 0;
foreach (PropertyInfo property in properties1)
{
var value = property.GetValue(item, null);
int n;
bool isNumeric = int.TryParse(value.ToString(), out n);
if (!isNumeric)
value = "Your desired value";
properties2[k].SetValue(current, value);
k++;
}
Lst2_.Add(current);
}
}
It copies everything from list 1 to list2.
No need to waste your time and money, AutoMapper can do it for you with only 2 lines of code:
using AutoMapper;
namespace ConsoleApp39
{
class Program
{
static void Main (string[] args)
{
// fill list1 with data
var list1 = new List1
{
Field1 = "test",
Field2 = 5,
Field3 = false,
};
// 1) configure auto mapper
Mapper.Initialize (cfg => cfg.CreateMap<List1, List2> ());
// 2) create list2 and fill with data from list1
List2 list2 = Mapper.Map<List2> (list1);
// fill extra fields
list2.Field4 = new byte[] { 1, 2, 3 };
}
}
public class List1
{
public string Field1 { get; set; }
public int Field2 { get; set; }
public bool Field3 { get; set; }
}
public class List2
{
public string Field1 { get; set; }
public int Field2 { get; set; }
public bool Field3 { get; set; }
public byte[] Field4 { get; set; } // extra field
}
}
Do Lst1 can inheritance from Lst2?
Something like this,
the two lists:
[Serializable()]
public class Lst1
{
public string filed1 { get; set; }
public int filed2 { get; set; }
public bool filed100 { get; set; }
}
[Serializable()]
public class Lst2 : Lst1
{
public string filed101 { get; set; }
}
and one print extension
public static class CExtensions
{
public static string PropertyList(this Lst1 obj)
{
var props = obj.GetType().GetProperties();
var sb = new StringBuilder();
foreach (var p in props)
{
sb.AppendLine(p.Name + ": " + p.GetValue(obj, null));
}
return sb.ToString();
}
}
then using it:
class Program
{
static void Main(string[] args)
{
const int I = 15;
try
{
//init first list
List<Lst1> Lst1_ = new List<Lst1>();
Init(Lst1_);
//print it
Console.WriteLine("Lst1_");
Console.WriteLine(new string('-', I));
Lst1_.ForEach(x => Console.WriteLine(x.PropertyList()));
Console.WriteLine(new string('=', I));
Console.ReadKey();
//init second list
List<Lst1> Lst2_ = Lst1_.Cast<Lst1>().ToList(); //equivalent of two next lines
//List<Lst1> Lst2_ = new List<Lst2>().ConvertAll(x => (Lst1)x);
//Lst2_.AddRange(Lst1_);
//add one more
Lst2_.Add(new Lst2
{
filed1 = "101",
filed2 = 202,
filed100 = true,
filed101 = "10100"
});
//and print
Console.WriteLine("Lst2_");
Console.WriteLine(new string('-', I));
Lst2_.ForEach(x => Console.WriteLine(x.PropertyList()));
Console.WriteLine(new string('=', I));
Console.ReadKey();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.ReadKey();
}
}
private static void Init(List<Lst1> lst_)
{
for (int i = 1; i <= 3; i++)
{
lst_.Add(new Lst1
{
filed1 = i.ToString(),
filed2 = 2 * i,
filed100 = i % 2 == 0
});
}
}
}
enjoy =)
I'm trying to put data with linebreakes to one item in listbox
how I make a breaklines in this command?
listBox1.Items.Add("");
or other command
thanks
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var product = new Product
{
ProductName = "Some name",
Id = "123X",
Size = "Big",
OutOfStock = "true"
};
var itm = new ListBoxItem {Content = $"Product Name: {product.ProductName} {Environment.NewLine}" +
$"ID: {product.Id} {Environment.NewLine}" +
$"Size: {product.Size} {Environment.NewLine}" +
$"Out of stock {product.OutOfStock}"
};
listBox.Items.Add(itm);
}
}
public class Product
{
public string ProductName { get; set; }
public string Id { get; set; }
public string Size { get; set; }
public string OutOfStock { get; set; }
}
I am trying to add some values into my SelectList data member in my object but I get an error
public ActionResult Create()
{
var paf = new ProductAddForm();
paf.Sizes = new SelectList(m.GetProductSizes());
paf.Suppliers = new SelectList(m.GetAllSuppliersList(), "Id", "Name");
return View(paf);
}
that is my creat function, and the paf.Sizes / paf.Suppliers code does not work.
My productaddform class:
public class ProductAddForm
{
public double MSRP { get; set; }
public string Name { get; set; }
public string ProductId { get; set; }
public ICollection<SelectList> Sizes { get; set; }
public ICollection<SelectList> Suppliers { get; set; }
public string UPC { get; set; }
}
And my methods in my manager.cs
public IEnumerable<SupplierList> GetAllSuppliersList()
{
var fetchedObjects = ds.Suppliers.OrderBy(n => n.Name);
var Suppliers = new List<SupplierList>();
foreach (var item in fetchedObjects)
{
var s = new SupplierList();
s.Name = item.Name;
s.Id = item.Id;
Suppliers.Add(s);
}
return (Suppliers);
}
public List<string> GetProductSizes()
{
return new List<string>() { "Small", "Medium", "Large" };
}
Whats wrong?
Suppliers is a collection of SelectList. So you need to Add item into the collection
Change
paf.Suppliers = new SelectList(m.GetAllSuppliersList(), "Id", "Name");
to
paf.Suppliers.Add(new SelectList(m.GetAllSuppliersList(), "Id", "Name"));