I see that this question is getting quite a bit of attention, so I will post the solution to my answer. I hope this will help someone out there to get some idea on how to add data only to a specific column. :)
Just as a side note - This is a test application that I created, therefore the coding will not be the same as the coding in my original question. Also I used a dictionary to solve my problem. It works great!
Creating my Item and Supplier lists:
//I create my dummy suppliers
private string[] CONST_Supplies = { "Supplier 1", "Supplier 2", "Supplier 3", "Supplier 4" };
public MainWindow()
{
InitializeComponent();
//I add my dummy items into my datagrid
//These are the items that I want to compare prices with
List<ViewQuoteItemList> list = new List<ViewQuoteItemList>();
list.Add(new ViewQuoteItemList() { Item = "Item 1" });
list.Add(new ViewQuoteItemList() { Item = "Item 2" });
list.Add(new ViewQuoteItemList() { Item = "Item 3" });
list.Add(new ViewQuoteItemList() { Item = "Item 4" });
list.Add(new ViewQuoteItemList() { Item = "Item 5" });
list.Add(new ViewQuoteItemList() { Item = "Item 6" });
//Loading the items into the datagrid on application start
DataGridTest.ItemsSource = list;
//Adding my dummy suppliers to my supplier selection combobox
foreach (var supplier in CONST_Supplies)
ComboBoxTest.Items.Add(supplier);
}
My button click event:
private void Add_Click(object sender, RoutedEventArgs e)
{
//Select my supplier from my Supplier's combobox
var supplier = ComboBoxTest.SelectedItem as string;
//Create the Supplier column and bind it to my 'ViewQuoteItemList' class +
//I'm binding it to the unique supplier selected from my combobox
DataGridTextColumn columnFeedbackSupplier = new DataGridTextColumn();
columnFeedbackSupplier.Binding = new Binding("Suppliers[" + supplier + "]");
columnFeedbackSupplier.Binding.FallbackValue = "Binding failed";
columnFeedbackSupplier.CanUserReorder = true;
columnFeedbackSupplier.CanUserResize = true;
columnFeedbackSupplier.IsReadOnly = false;
columnFeedbackSupplier.Header = ComboBoxTest.SelectedItem as string;
foreach (var item in DataGridTest.ItemsSource as List<ViewQuoteItemList>)
if (!item.Suppliers.ContainsKey(supplier))
item.Suppliers.Add(supplier, string.Empty);
DataGridTest.Columns.Add(columnFeedbackSupplier);
}
My class:
public class ViewQuoteItemList
{
public ViewQuoteItemList()
{
Suppliers = new ObservableDictionary<string, string>();
}
public int Id { get; set; }
public string Item { get; set; }
public ObservableDictionary<string, string> Suppliers { get; set; }
}
And my Observable Dictionary where a lot of the work happens:
public class ObservableDictionary<TKey, TValue> : IDictionary<TKey, TValue>, INotifyCollectionChanged, INotifyPropertyChanged
{
private const string CountString = "Count";
private const string IndexerName = "Item[]";
private const string KeysName = "Keys";
private const string ValuesName = "Values";
private IDictionary<TKey, TValue> _Dictionary;
protected IDictionary<TKey, TValue> Dictionary
{
get { return _Dictionary; }
}
#region Constructors
public ObservableDictionary()
{
_Dictionary = new Dictionary<TKey, TValue>();
}
public ObservableDictionary(IDictionary<TKey, TValue> dictionary)
{
_Dictionary = new Dictionary<TKey, TValue>(dictionary);
}
public ObservableDictionary(IEqualityComparer<TKey> comparer)
{
_Dictionary = new Dictionary<TKey, TValue>(comparer);
}
public ObservableDictionary(int capacity)
{
_Dictionary = new Dictionary<TKey, TValue>(capacity);
}
public ObservableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
{
_Dictionary = new Dictionary<TKey, TValue>(dictionary, comparer);
}
public ObservableDictionary(int capacity, IEqualityComparer<TKey> comparer)
{
_Dictionary = new Dictionary<TKey, TValue>(capacity, comparer);
}
#endregion
#region IDictionary<TKey,TValue> Members
public void Add(TKey key, TValue value)
{
Insert(key, value, true);
}
public bool ContainsKey(TKey key)
{
return Dictionary.ContainsKey(key);
}
public ICollection<TKey> Keys
{
get { return Dictionary.Keys; }
}
public bool Remove(TKey key)
{
if (key == null) throw new ArgumentNullException("key");
TValue value;
Dictionary.TryGetValue(key, out value);
var removed = Dictionary.Remove(key);
if (removed)
//OnCollectionChanged(NotifyCollectionChangedAction.Remove, new KeyValuePair<TKey, TValue>(key, value));
OnCollectionChanged();
return removed;
}
public bool TryGetValue(TKey key, out TValue value)
{
return Dictionary.TryGetValue(key, out value);
}
public ICollection<TValue> Values
{
get { return Dictionary.Values; }
}
public TValue this[TKey key]
{
get
{
return Dictionary[key];
}
set
{
Insert(key, value, false);
}
}
#endregion
#region ICollection<KeyValuePair<TKey,TValue>> Members
public void Add(KeyValuePair<TKey, TValue> item)
{
Insert(item.Key, item.Value, true);
}
public void Clear()
{
if (Dictionary.Count > 0)
{
Dictionary.Clear();
OnCollectionChanged();
}
}
public bool Contains(KeyValuePair<TKey, TValue> item)
{
return Dictionary.Contains(item);
}
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
{
Dictionary.CopyTo(array, arrayIndex);
}
public int Count
{
get { return Dictionary.Count; }
}
public bool IsReadOnly
{
get { return Dictionary.IsReadOnly; }
}
public bool Remove(KeyValuePair<TKey, TValue> item)
{
return Remove(item.Key);
}
#endregion
#region IEnumerable<KeyValuePair<TKey,TValue>> Members
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return Dictionary.GetEnumerator();
}
#endregion
#region IEnumerable Members
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)Dictionary).GetEnumerator();
}
#endregion
#region INotifyCollectionChanged Members
public event NotifyCollectionChangedEventHandler CollectionChanged;
#endregion
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
public void AddRange(IDictionary<TKey, TValue> items)
{
if (items == null) throw new ArgumentNullException("items");
if (items.Count > 0)
{
if (Dictionary.Count > 0)
{
if (items.Keys.Any((k) => Dictionary.ContainsKey(k)))
throw new ArgumentException("An item with the same key has already been added.");
else
foreach (var item in items) Dictionary.Add(item);
}
else
_Dictionary = new Dictionary<TKey, TValue>(items);
OnCollectionChanged(NotifyCollectionChangedAction.Add, items.ToArray());
}
}
private void Insert(TKey key, TValue value, bool add)
{
if (key == null) throw new ArgumentNullException("key");
TValue item;
if (Dictionary.TryGetValue(key, out item))
{
if (add) throw new ArgumentException("An item with the same key has already been added.");
if (Equals(item, value)) return;
Dictionary[key] = value;
OnCollectionChanged(NotifyCollectionChangedAction.Replace, new KeyValuePair<TKey, TValue>(key, value), new KeyValuePair<TKey, TValue>(key, item));
}
else
{
Dictionary[key] = value;
OnCollectionChanged(NotifyCollectionChangedAction.Add, new KeyValuePair<TKey, TValue>(key, value));
}
}
private void OnPropertyChanged()
{
OnPropertyChanged(CountString);
OnPropertyChanged(IndexerName);
OnPropertyChanged(KeysName);
OnPropertyChanged(ValuesName);
}
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private void OnCollectionChanged()
{
OnPropertyChanged();
if (CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
private void OnCollectionChanged(NotifyCollectionChangedAction action, KeyValuePair<TKey, TValue> changedItem)
{
OnPropertyChanged();
if (CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, changedItem));
}
private void OnCollectionChanged(NotifyCollectionChangedAction action, KeyValuePair<TKey, TValue> newItem, KeyValuePair<TKey, TValue> oldItem)
{
OnPropertyChanged();
if (CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, newItem, oldItem));
}
private void OnCollectionChanged(NotifyCollectionChangedAction action, IList newItems)
{
OnPropertyChanged();
if (CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(action, newItems));
}
}
It's a lot of code, I know. Sorry I don't have the time to explain everything and how it works. I hope that you guys can figure this out by yourself ;) There is also a lot of extra functions in the class that you can use for various purposes.
Lastly, here is my XAML:
<Button x:Name="Add" Content="Add" HorizontalAlignment="Left" Margin="65,143,0,0" VerticalAlignment="Top" Width="75" Click="Add_Click"/>
<DataGrid x:Name="DataGridTest" CanUserAddRows="False" AutoGenerateColumns="False" HorizontalAlignment="Left" Margin="165,115,0,0" VerticalAlignment="Top" Height="279" Width="611" ColumnWidth="*">
<DataGrid.Columns>
<DataGridTextColumn x:Name="columnFeedbackSupplierItem" Header="Item" Binding="{Binding Item}"/>
</DataGrid.Columns>
</DataGrid>
<ComboBox x:Name="ComboBoxTest" HorizontalAlignment="Left" Margin="20,115,0,0" VerticalAlignment="Top" Width="120"/>
Note - The values in the datagrid can be edited when you double-click on a cell. Thank you for all the people that added to my question or helped me in the right direction. I hope this can help someone out there.