I have a ViewModel in a WPF Application with these two properties:
public Customer Customer { get; set; }
public ObservableCollection<Customer> Customers { get; set; }
Inside my view I Have a DXGrid. How do I bind the selected item to the customer property?
You should use SelectedRowsSource property. Bind it to ObservableCollection<Customer>. Your code will look like this:
public ObservableCollection<Customer> SelectedCustomers { get; set; }
public ObservableCollection<Customer> Customers { get; set; }
....
<dxg:GridControl ItemsSource="{Binding Customers}" AutoPopulateColumns="True">
<dxg:GridControl.View>
<dxg:TableView MultiSelectMode="Row" NavigationStyle="Row"
SelectedRowsSource="{Binding SelectedCustomers}" />
</dxg:GridControl.View>
</dxg:GridControl>
Related
I have a little problem with Entity Framework when trying to model the real life
problem.
I have 2 entity like this :
public class Person
{
public int Id { get; set; }
public ICollection<Task> Tasks{ get; set; }
}
public class Task
{
public int Id { get; set; }
public Person Assignee{ get; set; }
public Person Assigner{ get; set; }
}
but if I want to use Entity framework,it forces me to change my model like this that it is different from real life !!
public class Person
{
public int Id { get; set; }
public ICollection<Task> AssigneesTasks{ get; set; }
public ICollection<Task> AssignerTasks{ get; set; }
}
(i just have single one-to-many relation in fact)
what is the solution to keep my model according to real life model?
Well you might want to know what tasks a person has assigned to them, and what tasks they have assigned to others. If you don't want both Navigation properties you don't need them in EF. But you do need to tell EF which relationship the Navigation Property is for. EG:
public class Person
{
public int Id { get; set; }
[InverseProperty("Assignee")]
public ICollection<Task> Tasks { get; set; }
}
public class Task
{
public int Id { get; set; }
public Person Assignee { get; set; }
public Person Assigner { get; set; }
}
I'm working on a cinema application which allows users to surf through movies, cinema places and allows them to buy or reserve tickets. If a user reserved a ticket online, then the ticket must be activated in 12 hours by sellerperson who also uses the same program. I need to show the ticket informations on grid and need to make editable. Here's my database classes that must be included in query and have relationship with Sale class. (I want to select objects from Sale class which includes ti's related classes: Ticket, customer, movie, status and saloon infos.
Sale Class:
public class Sale
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[ForeignKey("CustomerId")]
public virtual Customer Customer { get; set; }
public int CustomerId { get; set; }
[ForeignKey("StatusId")]
public virtual Status Status { get; set; }
public int StatusId { get; set; }
public virtual Seller Seller { get; set; }
public DateTime SellDate { get; set; }
public double Price { get; set; }
[ForeignKey("TicketID")]
public virtual Ticket Ticket { get; set; }
public int TicketID { get; set; }
}
Ticket Class:
public class Ticket
{
public Ticket()
{
Seats = new List<Seat>();
}
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[ForeignKey("MovieId")]
public virtual Movie Movie { get; set; }
public int MovieId { get; set; }
public virtual List<Seat> Seats { get; set; }
public virtual TimeSpan SeanceTime { get; set; }
public bool IsActive { get; set; }
public DateTime BuyDate { get; set; }
[ForeignKey("SaloonId")]
public virtual Saloon Saloon { get; set; }
public int? SaloonId { get; set; }
public string TicketNumber { get; set; }
}
Customer Class:
public class Customer
{
public Customer()
{
Sales = new List<Sale>();
CreditCards = new List<CreditCard>();
}
[Key]
public int UserID { get; set; }
public virtual List<Sale> Sales { get; set; }
public virtual User User { get; set; }
[DataType(DataType.CreditCard)]
public virtual List<CreditCard> CreditCards { get; set; }
}
User Class:
public class User
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
}
Status Class(Holds info of tickets. Bought or reserved.)
public class Status
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public bool IsRez { get; set; }
public bool IsBuy { get; set; }
public bool IsCancel { get; set; }
public bool IsPaid { get; set; }
}
Saloon Class:
public class Saloon
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public string Name { get; set; }
public double salePrices { get; set; }
}
Movie Class:
public class Movie
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public string Name { get; set; }
}
I can't edit because in my select query I'm using anonymous type for selection. My query code:
var Source = entities.Sales.Where(w => w.Ticket.Saloon.CinemaPlace.ID == seller.CinemaPlace.ID).Select(s => new
{
CustomerName = s.Customer.User.Name,
CustomerSurname = s.Customer.User.Surname,
SalePrice = s.Price,
s.Status.IsBuy,
s.Status.IsCancel,
s.Status.IsPaid,
s.Status.IsRez,
MovieName = s.Ticket.BuyDate,
s.Ticket.Movie.Name,
SaloonName = s.Ticket.Saloon.Name,
s.Ticket.SeanceTime,
s.Ticket.TicketNumber
}).ToList();
RezervationsGrid.DataSource = Source3;
But in the grid, the datas couldn't be edited. Then I tried to join every single table using Linq to Entities queries but it didn't help either. Is there a way make a datasource from my related objects that allows edit option in grid? Thanks.
Anonymous types (those that you can declare via the new operator in the Select method) cannot have writable properties in .NET. That's why the grid is not editable. To take advantage of in-place editing, you need to instantiate objects of a real CLR type.
For this, you can declare a special ViewModel class with public properties that you should populate with values in the Select method using object initializer.
.Select(s => new SaleViewModel() {
CustomerName = s.Customer.User.Name,
SalePrice = Price
})
Note that you should not move the property initialisation logic to the ViewModel constructor to use it this way:
.Select(s => new SaleViewModel(s))
The object initialiser is the expression tree, which Entity Framework can translate into an SQL query. The constructor is just a method reference, so Entity Framework will reject such an expression. If you would like to use this approach, you will need to call the ToList method before the Select.
SaleViewModel can have the method accepting the DbContext class to save changes.
You also can select the Sale instances and use complex property paths in columns' field names (such as "Customer.User.Name"). This can probably help you to simplify the saving logic, as you will not need to find a model specific to a certain view model and copy modified property values.
I have a user registration page where i uses a tabbed layout.In the first tab i will enter the personal details and in the second tab I want to enter a couple of references provied by the user.
I have created a viewmodel and binded the viewmodel to the View.The problem is i cannot access properties in the Relation class in the View
I am using two simple models
public partial class WalkInn
{
public WalkInn()
{
this.tblWalkIn_Relation = new HashSet<WalkIn_Relation>();
}
public long WALKINID { get; set; }
public long LOGINID { get; set; }
public string CANDIDATE_NAME { get; set; }
public string FATHER_SPOUSE_NAME { get; set; }
public System.DateTime DOB { get; set; }
public virtual Login tblLogin { get; set; }
public virtual ICollection<WalkIn_Relation> tblWalkIn_Relation { get; set; }
}
public partial class WalkIn_Relation
{
public long RELATIONID { get; set; }
public long WALKINID { get; set; }
public string NAME { get; set; }
public string RELATION { get; set; }
public virtual WalkInn tblWalkInn { get; set; }
}
Viewmodel is as follows
public class WalkInnVM
{
public WalkInn WalkInn { get; set; }
public ICollection<WalkIn_Relation> WalkInRelation { get; set; }
}
View is as follows
#model CRM.Models.ViewModels.WalkInnVM
#{
ViewBag.Title = "Add2";
}
<h2>Add WalkInn</h2>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">Name</label>
#Html.TextBoxFor(model=>model.WalkInn.CANDIDATE_NAME)
**Cannot access the below code**
#Html.TextBoxFor(model=>model.WalkInn_Relation.Name)
I am trying to represent a graph with typed edges in an entity-framework code-first model. I am having quite a difficulty understanding how to set up the relationships correctly. I am calling the nodes in my graph 'Items' and the edges 'Relationships' Here is what I have:
public class Item : Learnable
{
public Boolean IsBeginningItem { get; set; }
public virtual List<Relationship> RelationshipsLeft { get; set; }
public virtual List<Relationship> RelationshipsRight { get; set; }
}
-
public class Relationship : Learnable
{
public Boolean IsPrerequisiteRelationship { get; set; }
public virtual RelationshipType RelationshipType { get; set; }
public int ItemLeftID { get; set; }
[ForeignKey("ItemLeftID")]
public virtual Item ItemLeft { get; set; }
public int ItemRightID { get; set; }
[ForeignKey("ItemRightID")]
public virtual Item ItemRight { get; set; }
}
And here is what I am getting:
How can I get the RelationshipsRight property of Item to correspond to the ItemLeft property of Relationship AND the RelationshipsLeft property of Item to correspond to the ItemRight property of Relationship?
Oh... and I guess I should explain that this is supposed to be a directed graph that I can navigate bidirectionally. :)
You can use the [InverseProperty] attribute to bind the correct pairs of navigation properties together:
public class Relationship
{
//...
public int ItemLeftID { get; set; }
[ForeignKey("ItemLeftID"), InverseProperty("RelationshipsRight")]
public virtual Item ItemLeft { get; set; }
public int ItemRightID { get; set; }
[ForeignKey("ItemRightID"), InverseProperty("RelationshipsLeft")]
public virtual Item ItemRight { get; set; }
}
My problem is as follows:
I am working with MVVM pattern and I would like to know how to detect changes of subproperties.
I have a textbox:
<TextBox Name="Descripcion" Text="{Binding AccionActual.Descripcion,Mode=TwoWay}" />
In the ViewModel I have the property:
Accion _accionActual;
public Accion AccionActual
{
get { return _accionActual; }
set
{
_accionActual = value;
RaisePropertyChanged("AccionActual");
}
}
The Accion entity definition is:
public partial class Accion : Entity
{
public Accion()
{
this.AccionesDocumentos = new HashSet<AccionDocumento>();
}
public int IdAccion { get; set; }
public int IdEmpleado { get; set; }
public string Descripcion { get; set; }
public string DescripcionDetalle { get; set; }
public bool Finalizada { get; set; }
public Nullable<int> IdExpediente { get; set; }
public Nullable<int> IdOrdenTrabajo { get; set; }
public bool Facturable { get; set; }
public Nullable<short> GestComAlbaranAƱo { get; set; }
public Nullable<short> GestComAlbaranEmpresa { get; set; }
public Nullable<int> GestComAlbaranNumero { get; set; }
public bool Facturado { get; set; }
public bool ComputarHorasACliente { get; set; }
public string DescripcionInterna { get; set; }
public virtual Aplicacion Aplicacione { get; set; }
public virtual AplicacionModulo AplicacionesModulo { get; set; }
public virtual Cliente Cliente { get; set; }
public virtual ClienteContacto ClientesContacto { get; set; }
public virtual Empleado Empleado { get; set; }
public virtual Expediente Expediente { get; set; }
public virtual OrdenTrabajo OrdenesTrabajo { get; set; }
public virtual ICollection<AccionDocumento> AccionesDocumentos { get; set; }
}
I could create in the ViewModel a property for each of the properties of Accion, but there any way to receive the changes without having to create a property for each of the properties of Accion?
You have two choices- either modify the Accion class to implement INotifyPropertyChanged or create a ViewModel wrapper to do it.
Where you put this is up to you- do what works best for you. There is a question on the merits of doing it in the ViewModel vs Model class here.
You could take out the manual process of doing this by looking into something like notifypropertyweaver- try using Google to look for INotifyPropertyChanged Aspect Oriented Programming. There is a Stackoverflow question on it here.
This kind of redundant double wrapping by the ViewModel is a common problem in classic MVVM and drives me nuts too.
You have several options:
Have your entity implement INotifyPropertyChanged and expose the Entity to the View the way you did it with the AccionActual property.
Hide your Entity completely behind a corresponding ViewModel object, and add only those properties to the ViewModel that you actually need in the View. Introduce a clever change notification infrastructure that notifies your ViewModel about changes in the Model and raise PropertyChanged in your ViewModel accordingly. This "change notifcation infrastructure" could be an EventAggregator and maybe you can get away with some sort of bulk/meta update (e.g. raise NotifyPropertyChanged for all relevant properties in the ViewModel when you received the event "the entity changed".