Properties and objects C# - c#

I want to make public property that gets and sets object I get from datagrid.
I have datagrid that has 3 columns with text and 3 columns with checkboxes.
When I check one of the checkbox I get a value of whole row in list like this:
var selectedItemsController = MyObsCollection.Where(n => n.Controller).ToList();
That is a list of objects with all 3 string values (and all 3 bool values of checkboxes) that are in same row where checkboxes in column named Controller is.
MyObsCollection is also public property for ObservableCollection and they are defined like this:
ObservableCollection<RowData> _obsCollection =
new ObservableCollection<RowData>();
public ObservableCollection<RowData> MyObsCollection
{
get { return _obsCollection; }
}
RowData is my class that caries a model I need and it's defined like this:
public class RowData : INotifyPropertyChanged
{
public string Type { get; set; }
public string MapTo { get; set; }
public string Name { get; set; }
public bool Controller { get; set; }
public bool Service { get; set; }
public bool Injection { get; set; }
public RowData(string type, string mapTo, string name)
{
Type = type;
MapTo = mapTo;
Name = name;
}
What I'm trying to do is to make a public property for that list of objects(in selectedItemsController) so I can use it in other class.
For example I was doing this with name for some Area that is also part of WindowsForm. I was taking the name from some text box and making public property like this:
public string AreaName
{
get { return AreaNameValue.Text; }
set { AreaNameValue.Text = value; }
}
And after that I was able to do this in other class:
var areaName = areaDialog.AreaName.Trim();
So finally my question is does someone know how can I make same public property for DataRow object if the name of DataGrid is for example: tabela? Is there something already defined in DataGrid that I can use? (like 'Text' property is for InputTextBoxes).

You can set your selectedItemsController as the datacontext of your DataGrid. Then you can set and get values on the selectedItemsController itself.

Related

Assign property address to another property (reference). Change property when another property is changed. c#

I would like to assing one property to another in different class. Change this property automatically when passed property is changed. Something like reference the same address in c++. Is it possible in C#?
I want to achieve effect that when base property "IsOpen" in PressureValve class is changed, in the same time automatically propert "IsEnabled" in Component class is changed.
Thank you in advance for any help.
Classes:
class Component
{
public Component(int id, string description, ref anotherPropertyFromDifferentClass)
{
Id = id;
Description = description;
//Assign IsEnabled to another property, change it always when anotherPropertyFromDifferentClass is changed.
IsEnabled = ref anotherPropertyFromDifferentClass;
}
public int Id { get; set; }
public string Description { get; set; }
public bool IsEnabled { get; set; }
}
class PressureValve
{
public bool IsOpen { get; set; }
}
Program:
PressureValve pressureValve = new PressureValve();
//status read from external device, changing during programm running
pressureValve.IsOpen = externalInfo;
//create component, change component IsEnabled property automatically when pressureValve.IsOpen is changed
Component component = new Component(1,"Valve status", ref pressureValve.IsOpen)
Edit:
I would like to extend functionality suggested in accepted answer.
How to assign property from CommonProperty dynamically?
Example, more than one property in CommonPropertyclass:
class CommonProperty //Change this class name to Your desired one.
{
public bool IsOpen { get; set; }
public bool IsPoweredUp{ get; set; }
public bool IsRunning{ get; set; }
}
Then I would like to have multiple objects of Component class
class Component
{
public int Id { get; set; }
public string Description { get; set; }
public bool IsEnabled => //Here to assign property dynamically while creating object.
public CommonProperty ValveStatus { get; } //Set this only on Constructor since we want to update it automatically through the object reference
public Component(int id, string description, CommonProperty valveStatus)
{
Id = id;
Description = description;
ValveStatus = valveStatus;
//Assign IsEnabled to another property, change it always when anotherPropertyFromDifferentClass is changed.
}
}
And creation of object:
//create component, change component IsEnabled property automatically when assigned property from pressureValve is changed
Component component = new Component(1, "Valve status", commonProp, propertyName or type?);
You can use ref int to accomplish it, but would need more wiring.
This is the easiest way to do it and much cleaner to maintain. Also in the future if there are multiple parameters to auto-change, you can simply add them to the CommonProperty class:
Declare a Class for the properties to auto update:
class CommonProperty //Change this class name to Your desired one.
{
public bool IsOpen { get; set; }
}
Update the existing class definitions:
class PressureValve
{
public CommonProperty ValveStatus { get; set; }
}
class Component
{
public int Id { get; set; }
public string Description { get; set; }
public bool IsEnabled => ValveStatus.IsOpen; //Only Getter
public CommonProperty ValveStatus { get; } //Set this only on Constructor since we want to update it automatically through the object reference
public Component(int id, string description, CommonProperty valveStatus)
{
Id = id;
Description = description;
ValveStatus = valveStatus;
//Assign IsEnabled to another property, change it always when anotherPropertyFromDifferentClass is changed.
}
}
This is how you can you can accomplish it easiest without much change,
Here's how to test it:
PressureValve pressureValve = new PressureValve();
var commonProp = new CommonProperty {IsOpen = externalInfo};
//status read from external device, changing during programm running
pressureValve.ValveStatus = commonProp;
//create component, change component IsEnabled property automatically when pressureValve.IsOpen is changed
Component component = new Component(1, "Valve status", commonProp);
//Before Change
Console.WriteLine($"pressureValve IsEnabled: {pressureValve.ValveStatus.IsOpen.ToString()}");
Console.WriteLine($"component IsOpen: {component.IsEnabled.ToString()}");
//Change commonProp
commonProp.IsOpen = false; //since its an object, all the references in pressureValve & component will update
Console.WriteLine($"IsOpen Set to False");
//Check After Value Change
Console.WriteLine($"pressureValve IsEnabled: {pressureValve.ValveStatus.IsOpen.ToString()}");
Console.WriteLine($"component IsOpen: {component.IsEnabled.ToString()}");

Binding C# BindingList<T> to a DataGridView

Maybe the question is a little bit dumb, but I did not quite find solution anywhere else.
So I am using a BindingList of custom made class objects as a DataSource for DataGridView.
Everything works fine with properties, that are directly inherited from other classes, but if I have an object of other class in the main class, its properties wont show up in DataGridView.
Classes are:
enum Valsts
{
Latvija,
Igaunija,
Ķīna,
ASV
}
class Razotajs
{
public Valsts valsts { get; set; }
public string razotajaNosaukums { get; set; }
}
class Tehnika
{
public string krasa { get; set; }
public Razotajs razotajs = new Razotajs();
}
class Viedierice : Tehnika
{
public string operetajsistema { get; set; }
public double ekranaIzmers { get; set; }
public bool irHDMI { get; set; }
}
class MobilaisTelefons : Viedierice
{
public string modelis { get; set; }
public double svars { get; set; }
public SimKarte sim = new SimKarte();
public override string ToString()
{
return String.Join(";", modelis.ToString(),svars.ToString(),sim.veids.ToString(),operetajsistema.ToString(),ekranaIzmers.ToString(),irHDMI.ToString(),krasa.ToString(),razotajs.razotajaNosaukums.ToString(),
sim.numurs.ToString(),razotajs.valsts.ToString());
}
}
class SimKarte
{
public string veids { get; set;}
public int numurs { get; set; }
}
For example- I can see columns "modelis" and "svars", but attributes like "veids" and "numurs" from class SimKarte are not included in the DataGridView.
Is there any solution for this?
I've tried to add { get; set; } after declaring a new instance of an object in the class, but it's not even a real thing. I really don't have any idea, what would help me to solve this.
Thank you all in advance! :)
Honestly, I think the simplest solution is the one JohnG proposed; add proxy properties to your main class that read/write the properties of the complex objects
A datagridview will show only the simple types it knows how to show, from the top level class. It will not dig into properties of properties (otherwise even adding a string column would cause the grid to fill up with a Length column an Isinterned column etc..)
partial class MobilaisTelefons : Viedierice
{
public string modelis { get; set; }
public double svars { get; set; }
public SimKarte sim { get; set; } = new SimKarte();
public override string ToString()
{
return String.Join(";",
modelis, svars, sim.veids, operetajsistema, ekranaIzmers, irHDMI, krasa, razotajs.razotajaNosaukums,
sim.numurs, razotajs.valsts);
}
}
partial class MobilaisTelefons {
public string SimVeids { get => sim.veids; set => sim.veids = value; }
public string SimNumers { get => sim.numers; set => sim.numers = value; }
public string RazotajsRazotajaNosaukums { get => razotajs.razotajaNosaukums; set => razotajs.razotajaNosaukums = value; }
public Valsts RazotajsValsts { get => razotajs.valsts; set => razotajs.valsts = value; }
}
Few tips:
I made the extension of the class partial so you can put it in another file. Hiding its members from intellisense would be hard work
the Enum column will probably show as an int. if you want it to be sensible, use a DataGridViewComboBox column bound to a list of all the enum values/names. On the column, set the DataMember to "RazotajsValsts", the DataSource to the list of enums, the DisplayMember to the property representing the enum name and the ValueMember to the property representing the enum value. See Enum.GetValues.
Enums should only have a plural name (if valsts is plural) if they are flags
classes should not have a plural name
public properties names should be in PascalCase not camelCase
I simplified your tostring: you don't need to call to string on everything; string join will do it. You especially don't need to call tostring on a string

C# DefaultModelBinder does not bind property of type "dynamic"

I have been trying to figure this one out for the past 2 days...
My main model contains a property of type "dynamic" and looks like this:
public class WGTTestModel
{
private dynamic _oProp3 = null;
public WGTTestModel()
{
}
public int Prop1 { get; set; }
private string Prop2 = null;
public dynamic Prop3
{
get
{
if (_oProp3 == null)
{
// depending on other factors, this could return a different model
_oProp3 = new SubModel1();
}
return _oProp3 ;
}
set
{
_oProp3 = value;
}
}
}
SubModel1 looks like this:
public class SubModel1
{
public SubModel1()
{
}
public int Prop1 { get; set; }
public string Prop2 { get; set; }
}
The property "WGTTestModel.Prop3" is passed through to a partial view like so:
#Html.Partial("~/MVCFrontEnd/Widgets/TESTING/Views/_PartialView.cshtml", (object)Model.Prop3)
Note that I had to add the cast to (object) as it was not allowing me to pass along a "dynamic" type.
Problem: Values that I set on properties "SubModel1.Prop1" & "SubModel1.Prop2" in my partial view do not bind when posting the form.
The other test I made is by changing the type of "Prop3" from "dynamic" to "SubModel1" in my "WGTTestModel". I was then able to remove the cast to object when passing the model over to the partial view. This time everything works as expected and values bind correctly.
Is the DefaultModelBinder unable to bind "dynamic" type properties? If so, is there any possible workaround?
Any help will be appreciated!

Binding Complex Class object into datagridview in winforms

We have two class and there is relation with many to one company and product. So when we display product then we show the product name with company, so there is any direct way to bind DataGridvView.
public class Product : Common
{
public Int32 ProductID { get; set; }
[MaxLength(100)]
public string ProductName { get; set; }
public virtual ProductType ProductOfType { get; set; }
public virtual Company ProductCompany { get; set; }
public virtual PackageType ProductPackageType { get; set; }
}
DGProduct.DataSource = db.Product.toList(), so when we bind the DataGridvView then its show MedicineEntity.ProductCompany as rows, so there is any way to direct binding or need to bind manually using loop. Please some one suggest if any option is available, otherwise need to bind DataGridvView using loop or convert list into datatable.
The simplest way is to define ToString method on Company class.
class Company
{
public override string ToString()
{
return this.Name;
}
}
Others methods involves manually specifying columns in DataGridView
One approach involves writing custom TypeDescriptionProvider and decorating Company class with TypeDescriptionProviderAttribute. Use this article for full code: How to bind a DataGridView column to a second-level property of a data source
[TypeDescriptionProvider(typeof(CompanyDescriptionProvider))]
class Company
{
// ...
}
class CompanyDescriptionProvider : TypeDescriptionProvider
{
// implementation
}
Another is to define BoundField and add it to your grid:
public class CompanyField : BoundField
{
protected override string FormatDataValue(object dataValue, bool encode)
{
var obj = dataValue as Company;
if (obj != null)
{
return obj.Name;
}
else
{
return base.FormatDataValue(dataValue, encode);
}
}
}

DataValue field value C#

I am doing a project and can't make a Seletect Value from a list get the right value.A list is generated from a class UserDepartment,in this class I have this basically:
public class UserDepartment
{
public long ID { get; set; }
public string Description { get; set; }
public User UserResponsible { get; set; }
}
The Problem is that I need a value from the class userResponsible,inside there is a value called EDV, I need this value but I don't know how to get.See this image below:
If I use " ListBeneficiaryArea.DataValueField = "ID"; ",I get the ID value normally,but i cant get the EDV value, I already tried "EDV","UserResponsible.EDV" and "UserResponsible"but it didn't work.
There is other way for me to get the UserResponsible.EDV in the DataValueField?
After the change in DataSource i received this error:
You can change your DataSource to the following:
ListBeneficiaryArea.DataSource = from a in lstBUAreas
select new { ID, EDV = a.UserResponsible.EDV };
Then you can do:
ListBeneficiaryArea.DataTextField = "ID";
ListBeneficiaryArea.DataValueField = "EDV";

Categories