If having a List filled with objects of the following type:
public class Person {
public string Name { get; set; }
public string Ssn { get; set; }
}
How can one set the value of the property Name to be what's beeing displayed within an ASP.NET DropDown, without setting any properties on the ASP.NET DropDown object? Of course, one way would be to ovveride ToString() on the class Person, but is there any other way to accomplish the same thing?
Thanx!
You can create new control derived from DropDown (e.g. DropDownEx), introduce new attributes e.g. DisplayFieldAttribute, ValueFieldAttribute. Then use TypeDescriptor.GetProperties to enumerate properties and analyze attributes for binding them respectively.
Related
I have an issue trying to get a Checkbox working with ObjectListview.
My model looks like this:
public class object
{
public string name {get; set;}
public int age {get; set;}
public bool inuse {get; set;}
}
And I added a FastObjectListView via the Designer in Visual Studio to a Win Forms Application.
Then, I added the Columns and set the AspectName for each column to the Models Property (First column: AspectName: name, Second Column: AspectName: age, Third Column: AspectName: inuse).
Afterwards, I filled the ListView with this:
using (var context = new objectDb())
{
var objectlist = context.objects.ToList();
fastoLV_Clean.SetObjects(objectlist);
fastoLV_Clean.Refresh();
}
That works, and I can see my Database entries in the ListView.
Now I want to add a CheckBox column where someone can check or uncheck the items to delete them and I can not get the checkbox to work.
I have added a Column and set CheckBox to true, changed the CheckedAspectName of the ListView and now I can see the Checkboxes but nothing happens if I click them to check.
I think I'm on the completely wrong track, what do I have to do to make it work?
Thank you very much!!
I don't know a way with the ObjectListView to include any items which are not part of your model.
So then the simple way is to change your model to include a "Delete" property which you can then show in your ObjectListView.
Of course, this is not always possible! Especially if you are dealing with items that are written to/from Database or another persistence layer.
Then the trick is to write a derived class with you model being the base class and then you just add the delete column to this. But then you would need to convert from your Base to a derived class before showing in the ObjectListView.
The following code can help with that.
You keep your columns set-up as you have already done.
Assuming your (now base) class is defined like this
public class MyClass
{
public string name { get; set; }
public int age { get; set; }
public bool inuse { get; set; }
}
Your derived class inherits from this, adds the delete property and a new constructor
public class MySecondClass : MyClass
{
public bool Delete { get; set; }
public MySecondClass(MyClass other)
{
//Copy from MyClass
this.name = other.name;
this.age = other.age;
this.inuse = other.inuse;
//Set default for new properties
this.Delete = false;
}
}
Your code to retrieve the objects and set them then looks like this
using (var context = new objectDb())
{
var objectlist = context.objects.ToList();
//Now we need to convert to the derived class type
var secondlist = list.ConvertAll(x => new MySecondClass(x));
//Then we setobjects using this new list
fastoLV_Clean.SetObjects(secondlist);
}
I have a derived class with a property hiding the property in the parent class, like so:
public class Parent
{
public SomeObject Field { get; set; }
}
public class Child : Parent
{
public new SomeOtherObject Field{ get; set; }
}
Essentially, I'm binding a Kendo grid to an IEnumerable<Child> object and would like one of the columns to display the value of a property in Child.Field, i.e. Child.Field.SubField. However, when the code runs, it appears to be trying to bind to the super class' version of Field, which is null, hence throwing a NullReferenceException.
Is this expected behavior? If so, is there someway I can force MVC to bind to the child's version of the field? I was unable to find any documentation on either ASP.NET or Kendo about how they treat hidden properties.
What's the best way to design a class (or classes) that can hold the potential values of item, as well as the one the user actually selected? I've come across this problem before and always feel like I'm missing a core class design feature.
Right now I usually do something like the following
class MultiChoice
Name (I.e. Box Size)
Default Value ("22x15")
PotentialValues ({"10x10","20x20","22x15"})
But that doesn't handle the actual value the user selected, so I add that in.
class MultiChoice
Name (I.e. Box Size)
Default Value ("22x15")
PotentialValues ({"10x10","20x20","22x15"})
SelectedValue
That doesn't feel right though, because when I construct a drop-down I'm filling in stuff with SelectedValue = null. Then when I store the data, I'm storing all the options too, which I don't need.
Is there a better way to handle this with an interface or other language construct? I always feel like I'm missing something blatantly obvious here.
You really have two separate entities here:
MultiChoiceQuestion
MultiChoiceAnswer
Create two separate classes to represent these two separate concepts.
ASP.NET MVC has the SelectList class. While you might not actually be working in ASP.NET MVC, it seems clear that Microsoft felt that the concept of "backing class for a dropdown" was universal enough to warrant its own class.
In whatever you consider the "Model" (that part of your program containing the business domain classes and business logic), there will always exist database tables that serve as lookups for these dropdowns.
tblCountries
CountryID PK
CountryCode string
FullName string
In your ViewModel, there will be a corresponding list of countries from which you can populate the dropdown:
public class InvoiceViewModel
{
...
public int CountryID { get; set; }
public SelectList Countries { get; set; }
// or
public List<Country> Countries { get; set; }
...
}
Of course, by the time you get to the UI, the actual dropdown contains enough plumbing to hold both the select list and the selected value.
You really only need a single Value field. Set it to whatever you want in the constructor (so it's defaulted when the object is created). You can also change your 'potential values' to be static, so it's the same for the entire class.
public class Box
{
public string Value { get; set; }
public static List<string> AllowedValues { get; private set; }
public Box()
{
AllowedValues.AddRange(new string[]{"10x10","20x20","22x15"});
Value = AllowedValues.First();
}
}
Then when a user changes the value, simply update it.
Box thisBox = new Box();
string val = "22x15";
if (Box.AllowedValues.Contains(val))
thisBox.Value = val;
I have a class with similar structure as given below:-
public class Sample
{
public List<string> Names { get; private set; }
public List<int> IDs { get; private set; }
// Some logic to populate these collections.
}
Now in another XAML file, I need to bind Names property to a ComboBox and based on the selection I need to get the corresponding ID as selected value. Is there way I can solve this problem using binding?
I have an object of Sample class in my model like below:-
public class Model
{
public Sample Object
{
get { return _sample; }
set { _sample = value; }
}
}
I'm not allowed to change the Sample entity class. Please guide me on how to solve this problem.
You need to merge the two different lists into a single list of an object with two values before binding, fortunately doing so is rather straightforward, just use Zip:
var data = sample.Names.Zip(sample.IDs, (name, id)=> new{name, id});
Then bind to data as you normally would.
Your best bet is to wrap the Name and ID into a separate class, then bind the ItemsSource to the collection of Name/ID pairs. Set the DisplayMemberPath on the ComboBox to "Name".
On the View Model, you can have a property for the selected Name/ID pair, or just the selected ID. If you want to do the latter, just set SelectedValuePath to "ID" and bind SelectedValue to the ID property on your view model (note that if you do it this way, you can use the anonymous class projection from Servy's answer). Otherwise, just bind SelectedItem to your selected Name/ID pair property (this version requires a named class).
Is there a way to access the value of a dynamic field from another dynamic field template?
For example let's say that in my model I have something like this:
//auto generated by my data context
partial class Foo
{
public string Name { get; set; }
public bool ShouldGenerateNameDynamically { get; set ; }
}
[MetadataType(typeof(FooMetadata))]
partial class Foo{}
class FooMetadata
{
[UIHint("DynamicName")]
public object Name { get; set; }
}
So based on the value of ShouldGenerateNameDynamically I'd like to enable or disable and assign a calculated value to the Name field in my custom DynamicName template either in the PreRender or OnDataBinding events
So is there any way to send like an event across the dynamic data templates or access another field from a field template?