Reputation: 41
Im trying to bind one combobox from my class that i linked in the context
i have this in the control
<dxe:ComboBoxEdit Width="100" Margin="5" Name="cboProduct" DisplayMember="Name"
SelectedItem="{Binding Path=DataContext.SelectedProduct, Mode=OneWay, RelativeSource={RelativeSource AncestorType=Window}}"
>
</dxe:ComboBoxEdit>
I filled the Combobox befor from code behind like this
var lsproducts = new List<Product>();
var Products =_licenseService.GetProductList();
Products.ForEach((x) => {
lsproducts.Add(new Product(x.Name, x.ProductId));
});
And im setting the SelectedProduct like this
[DataMember]
public License SelectedLicense {
get { return _SelectedLicense;}
set {
_SelectedLicense = value;
this.NotifyPropertyChanged("SelectedLicense");
}
}
public Product SelectedProduct
{
get
{
return new Product(_SelectedLicense.Product.Name,_SelectedLicense.Product.ProductId);
}
}
this.cboProduct.ItemsSource = lsproducts.ToArray();
in both cases im using the object Product
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using pd.Common.Domain;
namespace LicenceManagerWPF.Views
{
public class Product
{
public string Name { get; set; }
public ProductEnum ProductID { get; set; }
public Product(string ProductName,ProductEnum ID)
{
Name = ProductName;
ProductID = ID;
}
}
i dont know why its not selecting the product when i open the window.
i have another one [![Shows like this][2]][2]
I dont know why its display the x mark, but when i chouse another licence it updated the combo selection
<dxe:ComboBoxEdit x:Name="cboActivationMode" Grid.Row="0" Grid.Column="1" HorizontalAlignment="Left" Width="100" Style="{StaticResource TabMargin}"
SelectedItem="{Binding Path=DataContext.SelectedLicense.ActivationMode, RelativeSource={RelativeSource AncestorType=Window}}"
/>
The second one its only a couple of enums values that fill like this.
cboActivationMode.Items.Add(
new DevExpress.Xpf.Editors.ComboBoxEditItem()
{ Content = Enum.GetName(typeof(ActivationMode), ActivationMode.Online), Tag = ActivationMode.Online });
How can i bind the values to a combobox? Regards
cboActivationMode.Items.Add(
new DevExpress.Xpf.Editors.ComboBoxEditItem()
{Content = Enum.GetName(typeof(ActivationMode), ActivationMode.Offline),Tag = ActivationMode.Offline});
I tryed to do this
public partial class LicenseDetail : UserControl
{
private readonly LicenseService _licenseService;
public LicenseDetail()
{
InitializeComponent();
_licenseService = new LicenseService();
FillCombos();
}
private void FillCombos()
{
FillProducts();
FillActivationMode();
//var str = Enum.GetName(typeof(ProductEnum), ProductEnum.CDSAddIn);
//this.cboProduct.ItemsSource = new string[] { str };
}
private void FillProducts()
{
var Products = _licenseService.GetProductList();
cboProduct.ItemsSource = Products;
}
The product list is a list of Iproduct (interface), i dont get i why they made it like this but each product is diferent they implement the same baseclass and the interface
[DataContract]
public class ProductList : List<IProduct>
{
public bool Contains(ProductEnum productId)
{
return this.Any(x => x.ProductId == productId);
}
public IProduct GetProduct(ProductEnum productId)
{
return this.FirstOrDefault(x => x.ProductId == productId);
}
public void Remove(ProductEnum productId)
{
Remove(GetProduct(productId));
}
}
I changed the combo to bind like this SelectedItem="{Binding Path=DataContext.MyProduct, RelativeSource={RelativeSource AncestorType=Window}}"
I create the property in the class like this public IProduct MyProduct { get { return _MyProduct; } set { _MyProduct = value; this.NotifyPropertyChanged("MyProduct"); } }
And assaing like this _CustomerLicense.MyProduct = SelectedLicense.Product;
this is how the list of products is filled public IProduct GetProduct(ProductEnum productId) { IProduct product = null;
var connection = GetConnection();
try
{
var sql = string.Format(Resources.GetProduct, (int)productId);
var cmd = new SqlCommand(sql, connection) { CommandType = CommandType.Text, Transaction = _transaction };
using (var rdr = new NullableDataReader(cmd.ExecuteReader()))
while (rdr.Read())
{
var productName = rdr.GetString(0);
var featureId = rdr.GetInt32(1);
var featureDesc = rdr.GetString(2);
if (product == null)
{
switch (productId)
{
case ProductEnum.PDCalc:
product = new PDCalcProduct(productId, productName);
break;
case ProductEnum.PDMaint:
product = new PDMaintProduct(productId, productName);
break;
case ProductEnum.PBDynamics:
product = new PBDynamicsProduct(productId, productName);
break;
case ProductEnum.CDSAddIn:
product = new CDSAddInProduct(productId, productName);
break;
}
}
if (product != null)
product.Features.Add(new Feature((FeatureEnum)featureId, featureDesc));
}
}
finally
{
CloseConnection(connection);
}
return product;
}
without any luck. Regards
Upvotes: 0
Views: 974
Reputation: 41
I fixed like this:
I created the method :
private void GetProducts()
{
var Products = new LicenseService().GetProductList();
Products.ForEach((x) =>
{
lsproducts.Add(new Product(x.Name, x.ProductId));
});
//this.cboProduct.ItemsSource = lsproducts.ToArray();
}
Then i attached to the load of the main windows, where all the controls are
public frmCustomerLicense(CustomerLicenses cl)
{
InitializeComponent();
GetProducts();
_CustomerLicense = cl;
grdLicenses.grdLicences.SelectedItemChanged += GridRowSelected;
}
Then when one of the licenses is selected i set all the bindings
var Record = (DataRowView)grdLicenses.grdLicences.SelectedItem;
var SelectedLicense = (License)Record["License"];
var list = new LicenseService().GetActivityLog(SelectedLicense.SerialNumber)
.OrderByDescending(x => x.ActivityDate)
.ToList();
_CustomerLicense.ActivityLog = list;
_CustomerLicense.Features = new LicenseService().GetFeatures(SelectedLicense.Product.ProductId);
_CustomerLicense.Products = lsproducts;
_CustomerLicense.HasExpDate = SelectedLicense.HasExpirationDate;
//_CustomerLicense.SetLog(list);
_CustomerLicense.SelectedLicense = SelectedLicense;
//_CustomerLicense.SelectedMaintenance = SelectedLicense.Product.ProductId == ProductEnum.PDMaint ? true : false;
_CustomerLicense.SelectedProduct = lsproducts.FirstOrDefault((x) => x.ProductID == SelectedLicense.Product.ProductId);
And in my ViewClass i added this
[DataMember]
public Product SelectedProduct
{
get { return _SelectedProduct; }
set
{
_SelectedProduct = value;
this.NotifyPropertyChanged("SelectedProduct");
}
}
[DataMember]
public List<Product> Products
{
get { return _Products; }
set { _Products = value;
this.NotifyPropertyChanged("Products");
}
}
So, i set the combobox
<dxe:ComboBoxEdit Width="180" Margin="5" Name="cboProduct" DisplayMember="Name"
ItemsSource="{Binding Path=DataContext.Products, RelativeSource={RelativeSource AncestorType=Window}}"
SelectedItem="{Binding Path=DataContext.SelectedProduct, RelativeSource={RelativeSource AncestorType=Window}}"
>
</dxe:ComboBoxEdit>
Doing this works, thanks for your help mm8
Upvotes: 0
Reputation: 169150
The SelectedProduct
property should have a public setter for you to be able to set it to the currently selected value in the ComboBox
:
private Product _selectedProduct;
public Product SelectedProduct
{
get { return _selectedProduct; }
set
{
_selectedProduct = value;
this.NotifyPropertyChanged("SelectedProduct");
}
}
And for the intial value to be selected, you either need to set it to a Product
object that is actually in the ItemsSource
(lsproducts
):
viewModel.SelectedProduct = lsproducts.FirstOrDefault(x => x.Name == _SelectedLicense.Product.Name && x.ProductID == _SelectedLicense.Product.ProductId);
Or you will have to override the Equals
method of your Product
class:
public class Product
{
public string Name { get; set; }
public ProductEnum ProductID { get; set; }
public Product(string ProductName, ProductEnum ID)
{
Name = ProductName;
ProductID = ID;
}
public override bool Equals(object obj)
{
Product other = obj as Product;
return other != null && Name == other.Name && ProductID == other.ProductID;
}
}
Upvotes: 1