Set SelectedItem for UWP ComboBox - mvvm

A UWP ComboBox ItemsSource displays correctly but the SelectedItem is not selected in the list. Why is that so?
The XAML:
<ComboBox Name="FooComboBox"
ItemsSource="{x:Bind ViewModel.Foos}"
SelectedItem="{x:Bind ViewModel.Foo,Mode=TwoWay,Converter={StaticResource ChangeTypeConverter}}"/>
ChangeTypeConverter comes from Template10
Foos and the value of the property Foo are set in the ViewModel
public class ViewModel : ViewModelBase
{
Foo _Foo = default(Foo);
public Foo Foo { get { return _Foo; } set { Set(ref _Foo, value); } }
public ObservableCollection<Foo> Foos = new ObservableCollection<Foo>(FooService.GetFoos());
public ViewModel()
{
Foo = FooService.GetDefaultFoo();
A Foo looks like this
public class Foo
{
public Guid FooId { get; set; } = Guid.NewGuid();
public string FooCode { get; set; }
public override string ToString()
{
return FooCode;
}
}
Yet although FooComboBox correctly renders the list of Foos, the SelectedItem is not set to the current value of the property Foo. Why is that so?

To turn the comments into an answer,
The SelectedItem should be an actual item inside the ItemsSource list, as determined by the Equals() method. In your case it was a separate instance and although it had the same Id it wasn't considered Equal.
There are several ways to solve this, perhaps the one that will solve similar issues down the road is to override Equals:
public class Foo
{
...
// untested
public override bool Equals(object obj)
{
Foo other = obj as Foo;
return FooId.Equals(other?.FooId);
}
}
but this has implications for the rest of your app. I would only consider using this to solve a SelectedItem issue when Foo is a ViewModel.
The other solution is to go find the actual item in the source list:
public ObservableCollection<Foo> Foos = ...;
public ViewModel()
{
var d = FooService.GetDefaultFoo();
Foo = Foos.FirstOrDefault(f => f.FooId == d.FooId);
}

Related

Autofac property injection with ValidationAttribute

I've got a ValidationAttribute that looks like this:
public class RegistrationUniqueNameAttribute : ValidationAttribute
{
public IRepository<User> UserRepository { get; set; }
public override bool IsValid(object value)
{
//use UserRepository here....
}
}
In my container setup (in app start) I have this:
builder.Register(c => new RegistrationUniqueEmailAttribute
{
UserRepository = c.Resolve<IRepository<User>>()
});
However, when debugging, the value of UserRepository is always null, so the property isn't getting injected.
Have I set up my container wrong?
I'd really rather not have to use DependencyResolver.Current.GetService<IRepository<User>>() as this isn't as testable...
No, Autofac v3 doesn't do anything special with ValidationAttribute and friends [Autofac.Mvc does lots of powerful things e.g., with filter attributes].
I solved the problem indirectly in this answer, enabling one to write:
class MyModel
{
...
[Required, StringLength(42)]
[ValidatorService(typeof(MyDiDependentValidator), ErrorMessage = "It's simply unacceptable")]
public string MyProperty { get; set; }
....
}
public class MyDiDependentValidator : Validator<MyModel>
{
readonly IUnitOfWork _iLoveWrappingStuff;
public MyDiDependentValidator(IUnitOfWork iLoveWrappingStuff)
{
_iLoveWrappingStuff = iLoveWrappingStuff;
}
protected override bool IsValid(MyModel instance, object value)
{
var attempted = (string)value;
return _iLoveWrappingStuff.SaysCanHazCheez(instance, attempted);
}
}
(And some helper classes inc wiring to ASP.NET MVC...)

Why the ViewModel doesn't implement ICommand in MVVM

I'm trying to understand MVVM for WPF applications
In the example below, we use a delegate that inherits from ICommand, then in our ViewModel, we instantiate the delegate and provide the appropriate implementation
My Question is why can't we just make the ViewModel implement ICommand?
ViewModel :
public class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
InitializeViewModel();
}
protected void InitializeViewModel()
{
DelegateCommand MyCommand = new DelegateCommand<SomeClass>(
SomeCommand_Execute, SomeCommand_CanExecute);
}
void SomeCommand_Execute(SomeClass arg)
{
// Implementation
}
bool SomeCommand_CanExecute(SomeClass arg)
{
// Implementation
}
}
DelegateCommand :
public class DelegateCommand<T> : ICommand
{
public DelegateCommand(Action<T> execute) : this(execute, null) { }
public DelegateCommand(Action<T> execute, Predicate<T> canExecute) : this(execute, canExecute, "") { }
public DelegateCommand(Action<T> execute, Predicate<T> canExecute, string label)
{
_Execute = execute;
_CanExecute = canExecute;
}
.
.
.
}
The reason would be having a one to many relationship between your view and your number of commands.
You typically will have one ViewModel for every View. But you may want to have many Commands for a single view. If you were to use your ViewModel as a Command, you would have to have multiple instances of your ViewModel.
The typical implementation would be that your ViewModel would contain instances of all of the Commands your View needs.
Short answer: because your ViewModel isn't a command.
Moreover, your ViewModel can hold multiple commands.
public class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
InitializeViewModel();
OpenCommand = new DelegateCommand<SomeClass>(
param => { ... },
param => { return true; });
SaveCommand = new DelegateCommand<SomeClass>(
param => { ... },
param => { return true; });
SaveAsCommand = new DelegateCommand<SomeClass>(
param => { ... },
param => { return true; });
}
public ICommand OpenCommand { get; private set; }
public ICommand SaveCommand { get; private set; }
public ICommand SaveAsCommand { get; private set; }
}
Now you can binding those commands to your view, because they are a property.
You can implement ICommand this way - and this is a very common way of implementing ICommand. That being said, you still need to make MyCommand a property on the ViewModel in order to bind to it.

Dynamic way to Generate EntityTypeConfiguration : The type 'TResult' must be a non-nullable value type

I was thinking to generate EntityTypeConfiguration dynamically from run time and i don't want any EF dependency in Models[That is why i avoid Data Annotation].
So I declare a custom attribute(or can be any configuration file later on)
[AttributeUsage(AttributeTargets.Property, AllowMultiple=true )]
public class PersistableMemberAttribute : Attribute
{
public bool Iskey;
public bool IsRequired;
public bool IsIgnored;
public bool IsMany;
public string HasForeignKey;
public bool PropertyIsRequired;
public bool PropertyIsOptional;
}
And here is one of my Models is look like:
public class Blog
{
[PersistableMember(Iskey=true)]
public Guid BlogId { get; set; }
[PersistableMember(PropertyIsRequired = true)]
public string Name { get; set; }
public string Url { get; set; }
[PersistableMember(IsIgnored=true)]
public int Rating { get; set; }
[PersistableMember(IsMany =true)]
public ICollection<Post> Posts { get; set; }
}
Now I am going to write a generic EntityTypeConfiguration , which will create the configuration dynamically on run time based on the attribute values :
public class GenericEntityConfiguration<T> : EntityTypeConfiguration<T> where T : class
{
public GenericEntityConfiguration()
{
var members = typeof(T).GetProperties();
if (null != members)
{
foreach (var property in members)
{
var attrb= property.GetCustomAttributes(typeof( PersistableMemberAttribute ),false).OfType<PersistableMemberAttribute>();
if (attrb != null && attrb.Count() > 0)
{
foreach (var memberAttributute in attrb)
{
if (memberAttributute.Iskey || memberAttributute.IsIgnored)
{
var entityMethod = this.GetType().GetMethod("Setkey");
entityMethod.MakeGenericMethod(property.PropertyType)
.Invoke(this, new object[] { property, memberAttributute });
}
if (memberAttributute.IsRequired)
{
var entityMethod = this.GetType().GetMethod("SetRequired");
entityMethod.MakeGenericMethod(property.PropertyType)
.Invoke(this, new object[] { property, memberAttributute });
}
if (memberAttributute.PropertyIsRequired || memberAttributute.PropertyIsOptional)
{
var entityMethod = this.GetType().GetMethod("SetPropertyConfiguration");
entityMethod.MakeGenericMethod(property.PropertyType)
.Invoke(this, new object[] { property, memberAttributute });
}
}
}
}
}
}
public void SetPropertyConfiguration<TResult>(PropertyInfo propertyInfo, PersistableMemberAttribute attribute)
{
var functorParam = Expression.Parameter(typeof(T));
var lambda = Expression.Lambda(
Expression.Property(functorParam, propertyInfo)
, functorParam);
if (attribute.PropertyIsRequired)
{
this.Property<TResult>((Expression<Func<T, TResult>>)lambda).IsRequired();
}
if (attribute.PropertyIsOptional)
{
this.Property<TResult>((Expression<Func<T, TResult>>)lambda).IsOptional();
}
}
public void Setkey<TResult>(PropertyInfo propertyInfo, PersistableMemberAttribute attribute)
{
var functorParam = Expression.Parameter(typeof(T));
var lambda = Expression.Lambda(
Expression.Property(functorParam, propertyInfo)
, functorParam);
if (attribute.Iskey)
{
this.HasKey<TResult>((Expression<Func<T,TResult>>)lambda);
}
if (attribute.IsIgnored)
{
this.Ignore<TResult>((Expression<Func<T, TResult>>)lambda);
}
}
public void SetRequired<TResult>(PropertyInfo propertyInfo, PersistableMemberAttribute attribute) where TResult : class
{
var functorParam = Expression.Parameter(typeof(T));
var lambda = Expression.Lambda(
Expression.Property(functorParam, propertyInfo)
, functorParam);
if (attribute.IsRequired)
{
this.HasRequired<TResult>((Expression<Func<T, TResult>>)lambda);
}
}
}
But i got the compilation error of
Error 1 The type 'TResult' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Data.Entity.ModelConfiguration.Configuration.StructuralTypeConfiguration.Property(System.Linq.Expressions.Expression>)' D:\R&D\UpdateStorePOC\UpdateStorePOC\Data\GenericEntityConfiguration.cs 63 17 UpdateStorePOC
which for these two statements:
this.Property<TResult>((Expression<Func<T, TResult>>)lambda).IsRequired();
this.Property<TResult>((Expression<Func<T, TResult>>)lambda).IsOptional();
that means that I need to put a constraint on my method to restrict it to a value type. In C#, this is done with the ‘struct’ keyword.
public void SetPropertyConfiguration<TResult>(PropertyInfo propertyInfo, PersistableMemberAttribute attribute) Where TResult : struct
But Its not the solution since my property type can be a class e.g string or int, bool double, etc . So it is not at all clear that I can send them into this method. Please help me to solve this issue whether there is any other way to do it.
I don't want any EF dependency in models.
With fluent mapping you're almost there and you won't come any closer. Your attributes, even though intended to be moved to a configuration file, don't make your model any more free of any EF footprint.1 Worse, they only add a second mapping layer (if you like) between your model and EF's mapping. I only see drawbacks:
You still have to maintain meta data for your model, probably not any less than regular fluent mapping and (probably) in awkward manually edited XML without compile-time checking.
You will keep expanding your code to cover cases that EF's mapping covers but yours doesn't yet.2 So it's a waste of energy: in the end you'll basically have rewritten EF's mapping methods.
You'll have to keep your fingers crossed when you want to upgrade EF.
With bugs/problems you're on your own: hard to get support from the community.
So my answer to your question help me to solve this issue would be: use fluent mapping out of the box. Keep it simple.
1 For example, you would still have to use the virtual modifier to enable proxies for lazy loading.
2 Like support for inheritance, unmapped foreign keys, max length, db data type, ... this could go on for a while.

EntityFramework 5 Code First - lookup table gets duplicate records

I am trying the EF5 CodeFirst and cannot get the simple setup to work ;(
I have two classes Foo and Bar where Bar represent lookup table.
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Bar Bar { get; set; }
}
public class Bar
{
public int Id { get; set; }
public string Description { get; set; }
}
public class MyDbContext : DbContext
{
static MyDbContext()
{
Database.SetInitializer<MyDbContext>(null);
}
public MyDbContext(): base("testEF"){}
public DbSet<Foo> Foos { get; set; }
public DbSet<Bar> Bars { get; set; }
}
Now I have created a static class that serves as DataAccess Layer - in real-world application it will be on different physical tier
public static class DataAccess
{
public static Bar GetBarById(int id)
{
using (var db = new MyDbContext())
{
return db.Bars.SingleOrDefault(b => b.Id == id);
}
}
public static Foo InsertFoo(Foo foo)
{
using (var db = new MyDbContext())
{
db.Foos.Add(foo);
db.SaveChanges();
}
return foo;
}
}
I am initializing the DB with seed method:
internal sealed class Configuration : DbMigrationsConfiguration<testEF.MyDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(testEF.MyDbContext context)
{
context.Bars.AddOrUpdate(
new Bar { Description = "Bar_1" },
new Bar { Description = "Bar_2" }
);
}
}
This creates two records in Bars table. So far so good...
Here is my Main function
static void Main(string[] args)
{
var bar1 = DataAccess.GetBarById(1);
var foo = new Foo
{
Name = "Foo_1",
Bar = bar1
};
DataAccess.InsertFoo(foo);
}
After the app runes there is a record in the Foos table:
Id Name Bar_Id
1 Foo_1 3
Why Bar_Id is 3? The EF actually inserted new record to Bars table!
Id Description
1 Bar_1
2 Bar_2
3 Bar_1
What I am doing wrong?
UPDATE:
I have found a workaround - to attach Bar property prior to inserting the record:
public static Foo InsertFoo(Foo foo)
{
using (var db = new MyDbContext())
{
db.Bars.Attach(foo.Bar);
db.Foos.Add(foo);
db.SaveChanges();
}
return foo;
}
It is working now but this is more like a hack than a valid solution...
In real-world application the complexity of the objects could become a huge problem.
I am open to better solutions
The problem is that bar1 comes from a different data context. Your InsertFoo method implicitly adds it to the second context by building a relationship with the Foo. You want these two to share a context. So use a single context for the whole scope of the Main method.
The complexity you mention (which I agree with you) is caused by using a static class for your data access component. It forces you to separate your DBContext's across method calls. Instead of doing it that way, why not create a normal class, and build the context in the constructor.
With this, you don't need to attach foo.Bar anymore.
public class DataAccess
{
private MyDbContext _context;
public DataAccess(){
_context = new MyDbContext();
}
public Bar GetBarById(int id)
{
return _context.Bars.SingleOrDefault(b => b.Id == id);
}
public Foo InsertFoo(Foo foo)
{
_context.Foos.Add(foo);
_context.SaveChanges();
return foo;
}
}
There are many ways you can build on and enhance this. You could create an interface for MyDbContext called IDbContext and using a DI framework inject it into this class. Similarly, you could do the same for the DataAccess class and inject that into wherever it's needed.

Can I make ServiceStack Deserialize json value of 1 as true?

Can I make ServiceStack Deserialize json value of 1 as true?
Here's a unit test showing what I want to do.
Is this possible? if so how?
public class Foo
{
public bool isWorking { get; set; }
}
...
[Test]
public void Deserialise1AsBoolean()
{
var json = #"{""isWorking"": 1}";
var myFoo = json.FromJson<Foo>();
Assert.IsTrue(myFoo.isWorking);
}
This is now built into ServiceStack.Text with this commit available from v3.9.55+.
EDIT Here's my solution, but please check out Mythz as well since I'm sure that will work also.
I deserialise to a custom struct MyBool rather than bool.
Here's the code for the MyBool struct.
public struct MyBool
{
public bool Value { get; set; }
public static MyBool Parse(string value)
{
return new MyBool {Value = (value == "1" || value=="true")};
}
public override string ToString()
{
return Value.ToString(CultureInfo.InvariantCulture);
}
public static implicit operator bool(MyBool lValue)
{
return lValue.Value;
}
and change Foo to:
public class Foo
{
public MyBool isWorking { get; set; }
}
Criticisms welcome.