How to solve this ComboBox item setting problem? - combobox

This code is not setting right value to the combobox. This is because, those are from different contexts.
In addition, in my actual problem, neither overloading == in nor overriding Equals() in MyClass is working as well.
Any alternative way?
How to solve this problem?
MyClass.cs
public class MyClass
{
public int ID { get; set; }
public string Name { get; set; }
public MyClass(int id, string name)
{
ID = id;
Name = name;
}
public static List<MyClass> Get()
{
return new List<MyClass>
{
new MyClass(2, "AAA"),
new MyClass(4, "BBB"),
new MyClass(5, "CCC"),
new MyClass(7, "DDD"),
new MyClass(10, "EEE")
};
}
}
ComboBoxForm.cs
public partial class ComboBoxForm : Form
{
public ComboBoxForm()
{
InitializeComponent();
}
private void Form1_Shown(object sender, EventArgs e)
{
LoadDataToComboBoxFromDatabase();
}
private void LoadDataToComboBoxFromDatabase()
{
comboBox1.Items.Clear();
List<MyClass> list = MyClass.Get();
foreach(MyClass mc in list)
{
comboBox1.Items.Add(mc);
}
comboBox1.DisplayMember = "Name";
comboBox1.ValueMember = "ID";
comboBox1.SelectedIndex = 0;
}
private void button1_Click(object sender, EventArgs e)
{
int ID = 5;//This is what I have.
comboBox1.SelectedItem = .............how?
}
}

I believe your Equals comparison may be incorrect. For NHibernate, I use the following Equals() method:
public static class EntityUtil
{
public static bool Equals(IEntity a, IEntity b)
{
// Transient entitys are never equal (unless they are ReferenceEquals)!
return
ReferenceEquals(a, b) || (
!((object)a == null || (object)b == null) &&
!(IsTransient(a) || IsTransient(b)) &&
NHibernateProxyHelper.GetClassWithoutInitializingProxy(a) == NHibernateProxyHelper.GetClassWithoutInitializingProxy(b) &&
a.Id.Equals(b.Id)
);
}
public static bool IsTransient(IEntity entity)
{
return entity.Id == 0;
}
}
I have defined this method in a separate helper class and use this in my entity:
public class Entity : IEquatable<Entity>, IEquatable<IEntity>
{
private int? _hashCode;
public virtual int Id { get; protected set; }
public override bool Equals(object obj)
{
return EntityUtil.Equals((IEntity)this, obj as IEntity);
}
public virtual bool Equals(Entity obj)
{
return EntityUtil.Equals((IEntity)this, (IEntity)obj);
}
public virtual bool Equals(IEntity obj)
{
return EntityUtil.Equals((IEntity)this, obj);
}
public static bool operator ==(Entity a, Entity b)
{
return EntityUtil.Equals((IEntity)a, (IEntity)b);
}
public static bool operator !=(Entity a, Entity b)
{
return !(a == b);
}
public override int GetHashCode()
{
// GetHashCode needs to return a stable value.
if (!_hashCode.HasValue)
{
_hashCode =
NHibernateProxyHelper.GetClassWithoutInitializingProxy(this).GetHashCode() ^
((IEntity)this).Id.GetHashCode();
}
return _hashCode.Value;
}
}
This is the suggested implementation for working with equality with NHibernate. Maybe this helps for you too.

Related

AutoFixture type customization not invoked

Given
This is my class structure being tested.
public class Company
{
public List<Department> Departments { get; set; }
}
public class Department
{
public List<Employee> Employees { get; set; }
}
public class Employee
{
public string Name { get; set; }
public DateTime HireDate { get; set; }
}
And I want to have an customized object of Employee added to Department.Employees when AutoFixture is told to Create<Company>().
I would think this should be written thus:
_fixture.Customize<Department>(
c => c.Do(d => d.Employees
.Add(_fixture.Build<Employee>()
.With(e => e.Name, "simple name")
.Create())));
_fixtrue.Create<Company>();
However
When I run the test, the Company.Departments property is populated with 3 objects, and each of those three objects has a Department.Employees list populated with 3 objects (expected 4 or 1) and none of the Employee objects have the name specified. Why?
Possibly relevant
I am also using the AutoNSubstituteCustomization and a homegrown implementation of ISpecimenBuilder for an unrelated type on the fixture.
That ISpecimenBuilder is:
public class PropertyTypeOmission
{
public SelectionContext<TDeclaringType> For<TDeclaringType>()
{
return new SelectionContext<TDeclaringType>();
}
public class SelectionContext<TDeclaringType>
{
public OmitMemberTypeByType Omitting<TPropertyType>()
{
return new OmitMemberTypeByType(typeof(TDeclaringType), typeof(TPropertyType));
}
public OmitMemberTypeByType Omitting<TMemberType>(Expression<Func<TDeclaringType, TMemberType>> select)
{
var memberExp = GetMemberExpression(select);
var property = GetPropertyInfo(memberExp);
if (property != null)
{
return new OmitMemberTypeByType(typeof(TDeclaringType), property.PropertyType);
}
var field = GetFieldInfo(memberExp);
if (field != null)
{
return new OmitMemberTypeByType(typeof(TDeclaringType), field.FieldType);
}
throw new ArgumentException("Only field or property selectors allowed");
}
private static PropertyInfo GetPropertyInfo(MemberExpression memberExp)
{
if (!(memberExp.Member is PropertyInfo property))
{
return null;
}
return property;
}
private static MemberExpression GetMemberExpression<TMemberType>(Expression<Func<TDeclaringType, TMemberType>> select)
{
if (!(select.Body is MemberExpression memberExp))
{
throw new ArgumentException("only member expressions are allowed");
}
return memberExp;
}
private static FieldInfo GetFieldInfo(MemberExpression memberExp)
{
if (!(memberExp.Member is FieldInfo field))
{
return null;
}
return field;
}
}
}
public class OmitMemberTypeByType : ISpecimenBuilder
{
private Type _declaringType;
private Type _memberType;
public OmitMemberTypeByType(Type declaringType, Type memberType)
{
_declaringType = declaringType;
_memberType = memberType;
}
public object Create(object request, ISpecimenContext context)
{
if ((!(request is PropertyInfo propertyInfo)
|| propertyInfo.DeclaringType != _declaringType
|| propertyInfo.PropertyType != _memberType)
&&
(!(request is FieldInfo fieldInfo)
|| fieldInfo.DeclaringType != _declaringType
|| fieldInfo.FieldType != _memberType))
{
return new NoSpecimen();
}
return new OmitSpecimen();
}
}
used as
_fixture.Customizations.Add(new PropertyTypeOmission().For<State>().Omitting(s => s.SqMiles));
The customization example you gave threw an exception for me.
It did that because the Employees property was not initialized, and then one of cource can't .Add() anything to it.
This worked for me:
List<Employee> EmployeesFactory((List<Employee> employees, Employee employee) input)
{
input.employee.Name = "simple name";
input.employees.Add(input.employee);
return input.employees;
}
_fixture
.Customize<Department>(c =>
c.With<List<Employee>, (List<Employee>, Employee)>(
x => x.Employees,
EmployeesFactory));

WPF: set log level and refresh collection after changing

So I have form that show my Application Log.
This is my Log model:
public class LogEntry : IComparable<LogEntry>
{
public string DateTime { get; set; }
public int Index { get; set; }
public string Source { get; set; }
public Level Level { get; set; }
public string Message { get; set; }
public int CompareTo(LogEntry other)
{
return DateTime.CompareTo(other.DateTime);
}
}
public enum Level
{
All = 0,
Debug,
Info,
Warn,
Error,
Fatal,
Off
}
Log Helper
This is my LogHelper class that add the current LogEvent according the level that the user selected:
public static class LogHelper
{
public static ObservableCollection<LogEntry> LogEntries { get; set; }
public static bool AddLogToList { get; set; }
private static int _level;
private static int _index;
private static string _formatPattern = "yyyy-MM-dd HH:mm:ss,fff";
public static void SetLevel(Level level)
{
_level = (int)level;
}
public static void AddLog(Level level, string message, string className, string methodName)
{
if (LogEntries == null)
LogEntries = new ObservableCollection<LogEntry>();
if (AddLogToList)
{
int levelValue = (int)level;
if (levelValue >= _level)
{
Application.Current.Dispatcher.Invoke(new Action(() =>
{
if (LogEntries.Count == 1000)
LogEntries.RemoveAt(LogEntries.Count - 1);
LogEntry logEntry = new LogEntry()
{
DateTime = DateTime.Now.ToString(_formatPattern),
Index = _index++,
Level = level,
Source = className + "\\" + methodName,
Message = message.Trim()
};
LogEntries.Insert(0, logEntry);
}));
}
}
}
}
So I am add LogEvent into my list that contains up ti 1000 entries.
Now I want to be able to filter and show my only the relevant LogEvent Level.
So I added ComboBox with all my LogEvent levels and subscribe to its SelectionChanged event:
private void cbLogLevel_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
int index = cbLogLevel.SelectedIndex;
LogHelper.SetLevel((Level)index);
lvLogger.ItemsSource = LogHelper.LogEntries.Where(m => m.Level == (Level)index).ToList();
}
So after this SelectionChanged event I can see the relevant LogEvent level but my only issue is the new LogEvent not shows.
Maybe I need kind of refresh to my collection or something else ?
You are creating a new List<LogEntry> and setting the ItemsSource property to this one in your event handler. This means that lvLogger will no longer be connected to the ObservableCollection.
Instead of resetting the ItemsSource, you could filter the view:
private void cbLogLevel_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
int index = cbLogLevel.SelectedIndex;
Level level = (Level)index;
LogHelper.SetLevel(level);
var collectionView = CollectionViewSource.GetDefaultView(lvLogger.ItemsSource);
collectionView.Filter = x =>
{
LogEntry logEntry = x as LogEntry;
return logEntry != null && logEntry.Level == level;
};
}

Cannot bind to the property or column States on the DataSource

Why this work :
public Form1()
{
InitializeComponent();
exCheckedListBox1.DataSource = Profiles;
this.exCheckedListBox1.DataBindings.Add(new System.Windows.Forms.Binding("Tag", this, "States", true));
}
CheckedBindingList Profiles = new CheckedBindingList();
public int States
{
get
{
return Profiles.States;
}
set
{
Profiles.States = value;
}
}
}
public class CheckedBindingList : List<string>
{
public int States { get; set; }
}
but when change binding to
this.exCheckedListBox1.DataBindings.Add(new System.Windows.Forms.Binding("Tag", this.Profiles, "States", true));
throw the Exception ?
Thanks all very very very. I try to bind filed from my custom list class that inherit form List.
Exception - Cannot bind to the property or column States on the DataSource.
Parameter name: dataMember
Seems System.Windows.Forms.Binding parameter dataSource cannot be a class that inherits from List< T >
This solves the problem:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Load += new EventHandler(Form1_Load);
}
CheckedBindingList Profiles = new CheckedBindingList();
SomeClass some_class = new SomeClass();
public int States
{
get
{
return Profiles.States;
}
set
{
Profiles.States = value;
}
}
private void Form1_Load(object sender, EventArgs e)
{
exCheckedListBox1.DataSource = Profiles;
exCheckedListBox1.DataBindings.Add(new System.Windows.Forms.Binding("Tag", some_class, "States", true));
}
}
public class CheckedBindingList : List<string>
{
public int States { get; set; }
}
public class SomeClass
{
public int States { get; set; }
}

How to create calculated Fields in Partial Classes - WPF

I am trying to use the calculated columns to display in my grid.
I have a partial class automatically generated by EF code generator with three properties: and i am trying to creating another partial class and add calculated field there for e.g.
Public partial class Employee
{
public decimal? totalSalary
{
get
{
return salary*wagerate+bonus;
}
}
}
It works fine for the first time but does not work when the salary/bonus/hours are changed. I am using these fields inside a grid
Here is my code generated by EF entity generator
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Globalization;
using System.Runtime.Serialization;
using System.ComponentModel.DataAnnotations;
namespace Employees.Contract
{
[DataContract(IsReference = true)]
[KnownType(typeof(Department))]
[KnownType(typeof(PropertyType))]
public partial class Employee: IObjectWithChangeTracker, INotifyPropertyChanged,IDataErrorInfo
{
[NonSerialized]
private CLOS.Contract.Validation.DataErrorInfoSupport dataErrorInfoSupport;
public Employee()
{
dataErrorInfoSupport = new CLOS.Contract.Validation.DataErrorInfoSupport(this);
Init();
}
partial void Init();
string IDataErrorInfo.Error { get { return dataErrorInfoSupport.Error; } }
string IDataErrorInfo.this[string memberName] { get { return dataErrorInfoSupport[memberName]; } }
#region Primitive Properties
[DataMember]
public Nullable<decimal> Salary
{
get { return _salary; }
set
{
if (_salary != value)
{
_salary = value;
OnPropertyChanged("Salary");
}
}
}
private Nullable<decimal> _salary;
[DataMember]
public Nullable<decimal> WageRate
{
get { return _wageRate; }
set
{
if (_wageRate != value)
{
_wageRate = value;
OnPropertyChanged("WageRate");
}
}
}
private Nullable<decimal> _wageRate;
[DataMember]
public Nullable<decimal> Bonus
{
get { return _bonus; }
set
{
if (_bonus != value)
{
_bonus = value;
OnPropertyChanged("Bonus");
}
}
}
private Nullable<decimal> _bonus;
#endregion
#region Navigation Properties
[DataMember]
public Department Department
{
get { return _department; }
set
{
if (!ReferenceEquals(_department, value))
{
var previousValue = _department;
_department = value;
OnNavigationPropertyChanged("Department");
}
}
}
private Borrower _department;
[DataMember]
public PropertyType PropertyType
{
get { return _propertyType; }
set
{
if (!ReferenceEquals(_propertyType, value))
{
var previousValue = _propertyType;
_propertyType = value;
OnNavigationPropertyChanged("PropertyType");
}
}
}
private PropertyType _propertyType;
#endregion
#region ChangeTracking
protected virtual void OnPropertyChanged(String propertyName)
{
if (ChangeTracker.State != ObjectState.Added && ChangeTracker.State != ObjectState.Deleted)
{
ChangeTracker.State = ObjectState.Modified;
}
if (_propertyChanged != null)
{
_propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
protected virtual void OnNavigationPropertyChanged(String propertyName)
{
if (_propertyChanged != null)
{
_propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged{ add { _propertyChanged += value; } remove { _propertyChanged -= value; } }
private event PropertyChangedEventHandler _propertyChanged;
private ObjectChangeTracker _changeTracker;
[DataMember]
public ObjectChangeTracker ChangeTracker
{
get
{
if (_changeTracker == null)
{
_changeTracker = new ObjectChangeTracker();
_changeTracker.ObjectStateChanging += HandleObjectStateChanging;
}
return _changeTracker;
}
set
{
if(_changeTracker != null)
{
_changeTracker.ObjectStateChanging -= HandleObjectStateChanging;
}
_changeTracker = value;
if(_changeTracker != null)
{
_changeTracker.ObjectStateChanging += HandleObjectStateChanging;
}
}
}
private void HandleObjectStateChanging(object sender, ObjectStateChangingEventArgs e)
{
if (e.NewState == ObjectState.Deleted)
{
ClearNavigationProperties();
}
}
protected bool IsDeserializing { get; private set; }
[OnDeserializing]
public void OnDeserializingMethod(StreamingContext context)
{
IsDeserializing = true;
}
[OnDeserialized]
public void OnDeserializedMethod(StreamingContext context)
{
dataErrorInfoSupport = new CLOS.Contract.Validation.DataErrorInfoSupport(this);
IsDeserializing = false;
ChangeTracker.ChangeTrackingEnabled = true;
}
protected virtual void ClearNavigationProperties()
{
Department = null;
PropertyType = null;
}
#endregion
}
}
It also works if i put OnPropertyChanged("Salary") in Hours,Wage,Overtime Property in EF Generated class (which is not a good idea) because if the class gets regenerated , my code will be wiped out
Any help is appreciated. (Sorry for the formatting , this is my first question)
Thanks
In the partial class use the partial Init method to subscribe to the PropertyChanged event and when either the salary, wagerate or bonus property changes notify clients of the change of the totalSalary.
This way you do not need to modify the generated code. (that is why the Init method is partial).
public partial class Employee
{
partial void Init()
{
_propertyChanged += PropertyChangedHandler;
}
void PropertyChangedHandler(object sender, PropertyChangedEventArgs args)
{
if(args.PropertyName == "salary" ||
args.PropertyName == "wagerate" ||
args.PropertyName == "bonus")
{
OnPropertyChanged("totalSalary");
}
}
public decimal? totalSalary
{
get
{
return salary * wagerate + bonus;
}
}
}
this is why MVVM is a popular design pattern, if you wrap your Employee (a Model) in a new class (a ViewModel), it will be easier to customise before you hand it to the grid (the View).
However, a hacky way to get your current code working would be to attach to the current PropertyChanged event in your partial class and call OnPropertyChanged("Salary") if the current property name matches one of the dependent properties (watch out for recursion!)

Calculated Properties using Partial Classes(WPF)

I am trying to use the calculated columns to display in my grid.
I have a partial class automatically generated by EF code generator with three properties:
Here is my code generated by EF entity generator
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Globalization;
using System.Runtime.Serialization;
using System.ComponentModel.DataAnnotations;
namespace Employees.Contract
{
[DataContract(IsReference = true)]
[KnownType(typeof(Department))]
[KnownType(typeof(PropertyType))]
public partial class Employee: IObjectWithChangeTracker, INotifyPropertyChanged,IDataErrorInfo
{
[NonSerialized]
private CLOS.Contract.Validation.DataErrorInfoSupport dataErrorInfoSupport;
public Employee()
{
dataErrorInfoSupport = new CLOS.Contract.Validation.DataErrorInfoSupport(this);
Init();
}
partial void Init();
string IDataErrorInfo.Error { get { return dataErrorInfoSupport.Error; } }
string IDataErrorInfo.this[string memberName] { get { return dataErrorInfoSupport[memberName]; } }
#region Primitive Properties
[DataMember]
public Nullable<decimal> Salary
{
get { return _salary; }
set
{
if (_salary != value)
{
_salary = value;
OnPropertyChanged("Salary");
}
}
}
private Nullable<decimal> _salary;
[DataMember]
public Nullable<decimal> WageRate
{
get { return _wageRate; }
set
{
if (_wageRate != value)
{
_wageRate = value;
OnPropertyChanged("WageRate");
}
}
}
private Nullable<decimal> _wageRate;
[DataMember]
public Nullable<decimal> Bonus
{
get { return _bonus; }
set
{
if (_bonus != value)
{
_bonus = value;
OnPropertyChanged("Bonus");
}
}
}
private Nullable<decimal> _bonus;
#endregion
#region Navigation Properties
[DataMember]
public Department Department
{
get { return _department; }
set
{
if (!ReferenceEquals(_department, value))
{
var previousValue = _department;
_department = value;
OnNavigationPropertyChanged("Department");
}
}
}
private Borrower _department;
[DataMember]
public PropertyType PropertyType
{
get { return _propertyType; }
set
{
if (!ReferenceEquals(_propertyType, value))
{
var previousValue = _propertyType;
_propertyType = value;
OnNavigationPropertyChanged("PropertyType");
}
}
}
private PropertyType _propertyType;
#endregion
#region ChangeTracking
protected virtual void OnPropertyChanged(String propertyName)
{
if (ChangeTracker.State != ObjectState.Added && ChangeTracker.State != ObjectState.Deleted)
{
ChangeTracker.State = ObjectState.Modified;
}
if (_propertyChanged != null)
{
_propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
protected virtual void OnNavigationPropertyChanged(String propertyName)
{
if (_propertyChanged != null)
{
_propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged{ add { _propertyChanged += value; } remove { _propertyChanged -= value; } }
private event PropertyChangedEventHandler _propertyChanged;
private ObjectChangeTracker _changeTracker;
[DataMember]
public ObjectChangeTracker ChangeTracker
{
get
{
if (_changeTracker == null)
{
_changeTracker = new ObjectChangeTracker();
_changeTracker.ObjectStateChanging += HandleObjectStateChanging;
}
return _changeTracker;
}
set
{
if(_changeTracker != null)
{
_changeTracker.ObjectStateChanging -= HandleObjectStateChanging;
}
_changeTracker = value;
if(_changeTracker != null)
{
_changeTracker.ObjectStateChanging += HandleObjectStateChanging;
}
}
}
private void HandleObjectStateChanging(object sender, ObjectStateChangingEventArgs e)
{
if (e.NewState == ObjectState.Deleted)
{
ClearNavigationProperties();
}
}
protected bool IsDeserializing { get; private set; }
[OnDeserializing]
public void OnDeserializingMethod(StreamingContext context)
{
IsDeserializing = true;
}
[OnDeserialized]
public void OnDeserializedMethod(StreamingContext context)
{
dataErrorInfoSupport = new CLOS.Contract.Validation.DataErrorInfoSupport(this);
IsDeserializing = false;
ChangeTracker.ChangeTrackingEnabled = true;
}
protected virtual void ClearNavigationProperties()
{
Department = null;
PropertyType = null;
}
#endregion
}
}
It also works if i put OnPropertyChanged("Salary") in Hours,Wage,Overtime Property in EF Generated class (which is not a good idea) because if the class gets regenerated , my code will be wiped out
Any help is appreciated. (Sorry for the formatting , this is my first question)
Thanks
Final Draft
(I removed old edits due to irrelevance)
In your partial class add, in addition to your definition of Salary:
partial void Init()
{
_propertyChanged += NotifySalary;
}
private void NotifySalary(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Wages" || e.PropertyName == "Hours" || e.PropertyName == "Overtime")
{
OnPropertyChanged("Salary");
}
}
I was able to fix this issue. What was happening is that service was marshaling the data back to the UI but it was not marshaling the events with the properties, so what i had to do was to call the init method from the UI and it started working.

Resources