DevExpress LookUp repository item binded to dictionary set members - c#

I have created a dictionary with an int key and a string value. I managed to set the dictionary as the datasource of my LookUp field. The lookup field is a repository item in a devexpress GridControl. The dictionary values are shown in my LookUp but I want to set the display and value member (and the caption) and don't know how to do this. Below you can see the current situation.
The dictionary code:
Dictionary<int, string> IncIncControls = new Dictionary<int,string>()
{
{ 1, "IncIncidentId"},
{ 2, "IncIncidentType"},
{ 3, "IncIncidentPriority"}
};
And the code to set the LookUp source
pageFieldLookUp.DataSource = (from d in IncIncControls
orderby d.Value
select new
{
d.Key,
d.Value
}).ToList();
How to modify the code to set lookup source in a way that I can set the display member/value member and caption. Or is there another (better) way to do this?

You can simply use RepositoryItemLookUpEditBase.DisplayMember and RepositoryItemLookUpEditBase.ValueMember properties for set display and value members, and use RepositoryItemLookUpEdit.Columns property to set captions:
pageFieldLookUp.DataSource = (from d in IncIncControls
orderby d.Value
select new
{
d.Key,
d.Value
}).ToList();
pageFieldLookUp.ValueMember = "Key";
pageFieldLookUp.DisplayMember = "Value";
pageFieldLookUp.PopulateColumns();
pageFieldLookUp.Columns[0].Caption = "Key caption";
pageFieldLookUp.Columns[1].Caption = "Value caption";

Related

Retrieve a ListViewItem's value

I have a ListView populated with the code below. Ask you can see, I set both the DisplayMember and the ValueMember. What I am wanting to do is find a ListViewItem by its ValueMember. So essentially what I'm looking for is ListViewItem.Value. I know I can get SelectedValue for the ListView itself, but I just don't see any properties on the ListViewItem that give me what I'm looking for. Am I just missing something, or is there no way to do this?
private void PopulateList(Globals.DataFieldMappingTypes mappingType)
{
ListBox lst = GetListBox(mappingType);
ComboBox cbo = cboh.GetComboBox(new ComboBoxHandler.CboInfo(Globals.NodeTypes.DataField, mappingType));
string sql = "select DataFieldReferenceValueId, [Value] from DataFieldReferenceValueInfo where DataFieldId = " + cbo.SelectedValue.ToString();
DataTable tbl = dal.GetTable(sql, "DataFieldReferenceValue");
lst.DisplayMember = "Value";
lst.ValueMember = "DataFieldReferenceValueId";
lst.DataSource = tbl.DefaultView;
}
I think that you are not getting the values from DataTable correctly I guess.
I hope tbl.Rows[0][0].ToString() will have the DataFieldReferenceValueId and
tbl.Rows[0][1].ToString() will have the [Value]
Please check the below MSDN link
https://forums.asp.net/t/1188002.aspx?how+to+read+DataTable+Rows+value+and+put+it+into+the+string+
Instead of loading your dataTable straight in as the dataSource why don't you create a class to define the values?
public class SqlTable
{
public string Name {get;set;}
public string Value {get;set;}
}
var listPair = new List<SqlTable>();
Then load the list with your SqlDataReader and grab your desired pair with LINQ.
while (sdr.Read())
{
listPair.Add(new SqlTable() { Name = sdr[0].ToString(), Value = sdr[1].ToString() });
}
lst.DisplayMember = "Name";
lst.ValueMember = "Value";
lst.DataSoure = listPair;
SqlTable sqlTable = listPair.Find(x => x.Name == "Whatever name you are searching for") as SqlTable;
The SqlTable item is now the one you are searching for and you can get its properties by going:
string value = sqlTable.Value;
string name = sqlTable.Name;
Edit from comment begins here:
Well your first issue is that the 'lst' item in your example is a ListBox and not a ListView. It you switch it to a listview you can still feed your List of listPair items like so:
ListView lst = new ListView();
lst.View = View.Details;
foreach (var data in listPair)
{
lst.Items.Add(new ListViewItem(listPair.Name, listPair.Value);
}
So now you have a ListView that is a collection of your listPairs where each listPair is a ListViewItem. I assume you want to isolate the ListViewItem based on your value (or listPair.Value or sdr[1] or [Value] they are all the same now) in order to color it. You can now grab the listPair item like so:
SqlTable pair = listPair.Find(x => x.Value == "Whatever the Value value is that you want to color");
ListViewItem searchedItem = lst.FindItemWithText(pair.Name);
searchedItem.BackColor = System.Drawing.Color.Red; //or whatever color you choose
You can now use searchedItem to grab its index in the ListView and all its other properties. The ListPair just allows you to associate the values.

LINQ in ItemBinding to add columns to DataGrid

I have a DataGrid bound to an ObservableCollection<MachineOrder> where I want to add some columns programmatically.
The object MachineOrder contains another ObservableCollection<KeyValue> from which I want to add the columns.
The thing is that I want to display a specific Key in the ObservableCollection for each row. The index isn't always the same so I cant use that.
I tried it this way:
foreach (StringWrapper characteristic in viewModel.Characteristics)
{
Binding binding = new Binding();
binding.FallbackValue = "kein Wert";
binding.Path = new PropertyPath("Charakteristics.FirstOrDefault(x => x.Key == characteristic.Value).Value");
DataGridTextColumn columnActive = new DataGridTextColumn();
columnActive.Header = characteristic.Value;
columnActive.Width = new DataGridLength(0, DataGridLengthUnitType.Auto);
columnActive.Binding = binding;
}
But the linq expression does not work here. Btw: viewModel.Characteristics contains a list of characteristics which I want to add to the DataGrid
Any ideas?
As you know, you can only bind to properties. So to solve the problem, just make a property and bind to it.
First, instead on ObservableCollection<KeyValue> create a custom derived collection to be used inside your MachineOrder class.
public class KeyValueCollection : ObservableCollection<KeyValue>
{
public Value this[string key]
{
get
{
var item = this.FirstOrDefault(x => x.Key == key);
return item != null ? item.Value : null;
}
}
}
The whole purpose is to define a new indexer property by key. Note that I don't have your KeyValue class, so the return type would be different.
Then you can bind to that property like this
foreach (StringWrapper characteristic in viewModel.Characteristics)
{
// ...
binding.Path = new PropertyPath("Characteristics[\"" + characteristic.Value + "\"]");
//...
}

How to set selectedValue to Controls.Combobox in c#?

I have a combobox and I see that I am not able to set SelectedValue like this:
cmbA.SelectedValue = "asd"
So I tried to do this
cmbA.SelectedIndex = cmbA.FindString("asd");
Based on How to set selected value from Combobox?
I realised that my combobox is a System.Windows.Controls.ComboBox and not a System.Windows.Forms.ComboBox.
That means that FindString() is not available.
Based on User Control vs. Windows Form I get that forms are the container for controls, but I dont get why the Controls.ComboBox does not implement FindString().
Do I have to write my own code to do what FindString() does for Forms.ComboBox?
WPF ComboBoxes are not the same as WinForms ones. They can display a collection of objects, instead of just strings.
Lets say for example if I had
myComboBox.ItemsSource = new List<string> { "One", "Two", "Three" };
I could just use the following line of code to set the SelectedItem
myComboBox.SelectedItem = "Two";
We're not limited to just strings here. I could also say I want to bind my ComboBox to a List<MyCustomClass>, and I want to set the ComboBox.SelectedItem to a MyCustomClass object.
For example,
List<MyCustomClass> data = new List<MyCustomClass>
{
new MyCustomClass() { Id = 1, Name = "One" },
new MyCustomClass() { Id = 2, Name = "Two" },
new MyCustomClass() { Id = 3, Name = "Three" }
};
myComboBox.ItemsSource = data;
myComboBox.SelectedItem = data[0];
I could also tell WPF I want to consider the Id property on MyCustomClass to be the identifying property, and I want to set MyCombbox.SelectedValue = 2, and it will know to find the MyCustomClass object with the .Id property of 2, and set it as selected.
myComboBox.SelectedValuePath = "Id";
myComboBox.SelectedValue = 2;
I could even set the Display Text to use a different property using
myComboBox.DisplayMemberPath = "Name";
To summarize, WPF ComboBoxes work with more than just Strings, and because of the expanded capabilities, FindString is not needed. What you are most likely looking for is to set the SelectedItem to one of the objects that exist in your ItemsSource collection.
And if you're not using ItemsSource, then a standard for-each loop should work too
foreach(ComboBoxItem item in myComboBox.Items)
{
if (item.Content == valueToFind)
myComboBox.SelectedItem = item;
}
I don't know what you are trying to do but I think it would be easier to just do
cmbA.Text = "String";
That way you get your selected item
Else I found an intersting article that could help you out:
Difference between SelectedItem, SelectedValue and SelectedValuePath

Binding Dictionary To Datagridview

I wanted to bind a dictionary to a datagridview. Unfortunately Dictionary does not implement the required interface, so instead a created a List>.
Essentially I want this to be bound to a datagridview with datagridviewcomboboxcolumns. With column 1 holding the Key and column 2 holding the value.
I've tried loads of variations, but I can't seem to get this right. I've tried binding to the columns, to individual cells, and to the datagridview itself. Does anybody know how to do this?
EDIT: To clarify it's not binding to the object that's the problem. It seems to binding to the List okay, for example, if I have 4 items in the List, then 4 rows are added, however the values are blank. This is the example code:
additionalMetadata1.dataGridView1.DataSource = animal.AdditionalMetaData;
foreach (DataGridViewRow row in additionalMetadata1.dataGridView1.Rows)
{
DataGridViewCustomComboCell cell = row.Cells[0] as DataGridViewCustomComboCell;
cell.DataSource = animal.AdditionalMetaData;
((DataGridViewCustomComboColumn)additionalMetadata1.dataGridView1.Columns[0]).DisplayMember = "Key";
((DataGridViewCustomComboColumn)additionalMetadata1.dataGridView1.Columns[0]).ValueMember = "Key";
((DataGridViewCustomComboColumn)additionalMetadata1.dataGridView1.Columns[0]).DataPropertyName = "Key";
}
Thanks.
You could use your Dictionary with the following Linq:
dataGridView.DataSource = (from d in dictionary
orderby d.Value
select new
{
d.Key,
d.Value
}).ToList();
This will create an anonymous object that will hold your Key and Value as properties. Be aware that the dictionary is by default not in a particular order.
Try like this
dataGridView1.ColumnCount = 2;
foreach (KeyValuePair<string, string> kvp in dict) {
string[] arow = new string[] { kvp.Key, kvp.Value };
dataGridView1.Rows.Add(arow);
}
or
dataGridView1.DataSource = dict.ToArray();
or
dataGridView1.DataSource = dict.Select((kv => new {
myKeys = kv.Key,
myValues = kv.Value
})).ToArray();

Sort Hashtable Data in ASP.NET C#

I am binding my dropdownlist with Enum I have following enum and code for bind dropdownlist.
public enum DignosisOrderType
{
All = 0,
General = 1,
Uveitis = 2,
Coag =3,
PreOp=4,
Tests=5,
RP =6
}
public static void BindDropDownByEnum(DropDownList dropDownList, Type enumDataSource, )
{
Hashtable htDataSource = new Hashtable();
string[] names = Enum.GetNames(enumDataSource);
Array values = Enum.GetValues(enumDataSource);
for (int i = 0; i < names.Length; i++)
htDataSource.Add(names[i], values.GetValue(i));
BindDropDown(dropDownList, htDataSource, "key", "value");
}
public static void BindDropDown(DropDownList dropDownList, object dataSource, string dataTextField, string dataValueField)
{
dropDownList.DataSource = dataSource;
dropDownList.DataTextField = dataTextField;
dropDownList.DataValueField = dataValueField;
dropDownList.DataBind();
}
when the Dropdownlist is bind the data is not comming in sorting order,I want dropdownlist is bind in order of Enum is created.
If you want the items in the order you're adding them, you don't want a hashtable or a SortedList. (A sorted list will be fine while you actually want them in the key sort order anyway, but if you later decide you need to tweak the order, it will cause problems.) In particular, you're not trying to use the ability to look up a value by key, so you don't need an IDictionary<,> at all as far as I can see.
You just want a List<T> for a type containing the key and value. You could do that with an anonymous type, for instance:
var keyValuePairs = Enum.GetValues(enumDataSource)
.Select(x => new { key = x.ToString(), value = x })
.ToList();
BindDropDown(dropDownList, keyValuePairs, "key", "value");
A HashTable isn't the tool for the job then. Try a SortedList.
Remember, A HashTable supports very fast searching, however it does not keep any ordering
There is actually a specialized collection called OrderedDictionary that gives you both abilities: sorting and keyed access.
One thing you could do is iterate through the HT in the BindDropDown method adding one ListItem at a time, so they would be ordered by index.
Just use SortedList or replace HashTable with SortedList

Categories