I have a simple WPF app with 3 textboxes, 2 of the text boxes input numbers and the third textbox shows the sum of inputs when another button is clicked.
I come from WinForms and MFC background and for me, the intuitive thing to do is to right click the textBoxes, open their properties and specify local variables to read the data from the boxes. For example, MFC has the DDX mechanism for this.
However, in WPF, the only way to specify a binding seems to add XAML code directly to App.XAML, as shown here on MSDN. Is there a way to create a binding without coding it manually into XAML? XAML coding seems a little daunting to me, since I am new to it.
My WPF form is as follows :
<Window x:Class="SimpleAdd.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBox HorizontalAlignment="Left" Height="23" Margin="174,43,0,0" TextWrapping="Wrap" Text="{Binding dataModel.Value1}" VerticalAlignment="Top" Width="120"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="174,84,0,0" TextWrapping="Wrap" Text="{Binding dataModel.Value2}" VerticalAlignment="Top" Width="120"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="174,127,0,0" TextWrapping="Wrap" Text="{Binding dataModel.Value3}" VerticalAlignment="Top" Width="120"/>
<Button Content="Add" HorizontalAlignment="Left" Margin="393,84,0,0" VerticalAlignment="Top" Width="75" Click="OnAdd"/>
</Grid>
</Window>
My C# file is as follows :
namespace SimpleAdd
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void OnAdd(object sender, RoutedEventArgs e)
{
dataModel m1 = new dataModel();
m1.Value3 = m1.Value1 + m1.Value2; // BUG : All Properties are 0 even after updating the boxes.
}
}
public class dataModel
{
private int val1, val2, val3;
public int Value1
{
get {return val1;}
set { val1 = value; }
}
public int Value2
{
get { return val2; }
set { val2 = value; }
}
public int Value3
{
get { return val3; }
set { val3 = value; }
}
}
}
EDIT : Adding implementation for INotifyPropertyChanged
namespace SimpleAdd
{
public abstract class ObservableObject : INotifyPropertyChanged
{
#region Debugging Aides
/// <summary>
/// Warns the developer if this object does not have
/// a public property with the specified name. This
/// method does not exist in a Release build.
/// </summary>
[Conditional("DEBUG")]
[DebuggerStepThrough]
public virtual void VerifyPropertyName(string propertyName)
{
// Verify that the property name matches a real,
// public, instance property on this object.
if (TypeDescriptor.GetProperties(this)[propertyName] == null)
{
string msg = "Invalid property name: " + propertyName;
if (this.ThrowOnInvalidPropertyName)
throw new Exception(msg);
else
Debug.Fail(msg);
}
}
/// <summary>
/// Returns whether an exception is thrown, or if a Debug.Fail() is used
/// when an invalid property name is passed to the VerifyPropertyName method.
/// The default value is false, but subclasses used by unit tests might
/// override this property's getter to return true.
/// </summary>
protected virtual bool ThrowOnInvalidPropertyName { get; private set; }
#endregion // Debugging Aides
#region INotifyPropertyChanged Members
/// <summary>
/// Raises the PropertyChange event for the property specified
/// </summary>
/// <param name="propertyName">Property name to update. Is case-sensitive.</param>
public virtual void RaisePropertyChanged(string propertyName)
{
this.VerifyPropertyName(propertyName);
OnPropertyChanged(propertyName);
}
/// <summary>
/// Raised when a property on this object has a new value.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Raises this object's PropertyChanged event.
/// </summary>
/// <param name="propertyName">The property that has a new value.</param>
protected virtual void OnPropertyChanged(string propertyName)
{
this.VerifyPropertyName(propertyName);
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
#endregion // INotifyPropertyChanged Members
}
}
Your TextBox are not being updated because you haven't set the data source (DataContext typically) behind the bindings.
When you write
<TextBox Text="{Binding dataModel.Value1}" />
What you are really saying "pull the value for this field from TextBox.DataContext.dataModel.Value1". If TextBox.DataContext is null, then nothing will be displayed.
The DataContext is inherited automatically, so the following code would work :
public partial class MainWindow : Window
{
public dataModel _data { get; set; }
public MainWindow()
{
InitializeComponent();
_data = new dataModel();
this.DataContext = _data;
}
private void OnAdd(object sender, RoutedEventArgs e)
{
_data.Value3 = _data.Value1 + _data.Value2;
}
}
assuming you also change your TextBox bindings to remove the dataModel. from them
<TextBox Text="{Binding Value1}" />
This sets the DataContext of the entire form to the _data object, and in your OnAdd method we can update the _data object properties in order to have the UI update.
I like to blog a bit about beginner WPF stuff, and you may be interested in checking out a couple of the posts there which explain these concepts :
Understanding the change in mindset when switching from WinForms to WPF
What is this "DataContext" you speak of?
Technically, that's not in App.xaml (which is a special file in WPF).
That said, yes you can do it. You can set up the binding in code like so:
textBox1.Text = new Binding("SomeProperty");
...
Okay, that gets really annoying so we just do it in XAML:
<TextBox Text="{Binding SomeProperty}"/>
Both pieces of code do the same thing, but when you get into more advanced bindings, the XAML syntax is a lot easier to use. Plus, its more obvious where you text is coming from rather than having to open two files.
The FrameworkElement class and the FrameworkContentElement class both expose a SetBinding method. If you are binding an element that inherits either of these classes, you can call the SetBinding method directly.
The following example creates a class named, MyData, which contains a property named MyDataProperty.
public class MyData : INotifyPropertyChanged
{
private string myDataProperty;
public MyData() { }
public MyData(DateTime dateTime)
{
myDataProperty = "Last bound time was " + dateTime.ToLongTimeString();
}
public String MyDataProperty
{
get { return myDataProperty; }
set
{
myDataProperty = value;
OnPropertyChanged("MyDataProperty");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string info)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(info));
}
}
}
The following example shows how to create a binding object to set the source of the binding. The example uses SetBinding to bind the Text property of myText, which is a TextBlock control, to MyDataProperty.
MyData myDataObject = new MyData(DateTime.Now);
Binding myBinding = new Binding("MyDataProperty");
myBinding.Source = myDataObject;
myText.SetBinding(TextBlock.TextProperty, myBinding);
Related
So I have a c# wpf application with a default layout and different UserControls to fill one part of that layout. So far everything worked like a charm with binding properties, but now that i created another UserControl the binding only seems to work OneWay.
View -> ViewModel works great, I can trace button clicks, comboboxes being checked and all that stuff, but ...
ViewModel -> View doesn't want to work at all.
I've tried setting the Mode of the Bindings to TwoWay and setting UpdateSourceTrigger to PropertyChanged, but nothing changes.
This is my View:
<UserControl ...
xmlns:vm="clr-namespace:Prueftool.BBCCreatorViewModel"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.DataContext>
<vm:CreateDisplayTypeViewModel/>
</UserControl.DataContext>
<Grid>
<Button Content="Button" Width="75" Command="{Binding TestButtonClick}"/>
<CheckBox Content="CheckBox" IsChecked="{Binding TestIsChecked}"/>
</Grid>
</UserControl>
And here is my referenced ViewModel:
namespace Prueftool.BBCCreatorViewModel
{
class CreateDisplayTypeViewModel : ViewModelBase, ICreateDisplayViewModel
{
private bool _testIsChecked;
public bool TestIsChecked
{
get { return _testIsChecked; }
set
{
_testIsChecked = value;
OnPropertyChanged("TestIsChecked");
}
}
public void SetNewDisplayType(DisplayType selectedDisplayType)
{
if(selectedDisplayType.Name == "Default")
{
TestIsChecked = true;
}
}
private DelegateCommand _random;
public ICommand RandomButtonClick
{
get
{
if (_random == null)
{
_random = new DelegateCommand(randomButtonClick);
}
return _random;
}
}
private void randomButtonClick()
{
if(TestIsChecked)
{
MessageBox.Show("Hello World");
}
}
}
}
The SetNewDisplayType method is being called and the if statement is true, but it won't check my combobox in the view. On the other hand, checking the combobox manually and then pressing the button fires the randomButtonClick method and a MessageBox appears.
EDIT:
OnPropertyChanged method (not mine)
#region public virtual void OnPropertyChanged()
/// <summary>
/// Raises this object's PropertyChanged event.
/// </summary>
/// <param name="propertyName">The property that has a new value.</param>
public virtual void OnPropertyChanged(string propertyName)
{
this.VerifyPropertyName(propertyName);
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
#endregion
I think you may be calling SetNewDisplayType on a different instance of CreateDisplayTypeViewModel than the one used as DataContext. The binding works and the checkbox is checked when I use your UserControl and change the Constructor to
public MyUserControl()
{
InitializeComponent();
((CreateDisplayTypeViewModel)DataContext).SetNewDisplayType();
}
and SetNewDisplayType to
public void SetNewDisplayType()
{
TestIsChecked = true;
}
It would help though if you could post how this function is called.
Edit: The fact that the handler in OnPropertyChanged is null (as you mentioned in the comments above) is also a hint that you might be using two instances of the VM.
I think you just need to implement INotifyPropertyChanged on your class.
class CreateDisplayTypeViewModel : ViewModelBase, ICreateDisplayViewModel, INotifyPropertyChanged
I see you have the OnPropertyChanged method but you would also need to implement to PropertyChangedEventHandler. Something like this should do it:
#region Public Events
public event PropertyChangedEventHandler PropertyChanged;
#endregion Public Events
#region Protected Methods
protected void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
#endregion Protected Methods
Okay I've been wracking my brain a lot about this one, I'm missing something, I just can't figure out what. Ultimately I'm trying to set databinding so I can update values to be shown on the fly, but for the life of me, it's not working.
The XAML is:
<TextBox x:Name="textBox" HorizontalAlignment="Left"
Height="37" Margin="85,38,0,0" TextWrapping="Wrap"
Text="{Binding Path=TBBind}" VerticalAlignment="Top"
Width="121" />
Note that I have the {Binding Path=TBBind} set.
The code behind is:
using System.ComponentModel;
using System.Windows;
namespace Databinding_Practice_2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
TBBind = "test";
}
private string _tBBind;
public string TBBind
{
get { return _tBBind; }
set
{
if (value != _tBBind)
{
_tBBind = value;
OnPropertyChanged("TBBind");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string property)
{
MessageBox.Show("OnPropertyChanged triggered");
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
}
Help me obi-w.... oh wait, help me anyone!
Assuming that you are trying to use the MVVM pattern (which stands for Model-View-ViewModel):
Your MainWindow is the View.
You should create another class to be the View Model, like this:
public class MainWindowViewModel : INotifyPropertyChanged
{
public MainWindowViewModel()
{
TBBind = "test";
}
private string _tBBind;
public string TBBind
{
get { return _tBBind; }
set
{
if (value != _tBBind)
{
_tBBind = value;
OnPropertyChanged("TBBind");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string property)
{
MessageBox.Show("OnPropertyChanged triggered");
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
Your MainWindow code behind will become like this after removing all ViewModel related stuff to the MainWindowViewModel class:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
Now, you should link the View with the ViewModel, there are many ways to do this. Here is one of them:
In the XAML of MainWindow, have the following inside the Window element:
<Window.DataContext>
<wpfApplication5:MainWindowViewModel />
</Window.DataContext>
<Grid>
<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="37" Margin="85,38,0,0" TextWrapping="Wrap" Text="{Binding TBBind}" VerticalAlignment="Top" Width="121" />
</Grid>
Please note that WpfApplication5 is the name of the namespace in my WPF project. This will probably be different in your case.
Try:
public MainWindow()
{
InitializeComponent();
DataContext = this;
TBBind = "test";
}
The difference here sets the critical DataContext property. This is the cornerstone of the MVVM pattern, which you are implementing here. You should consider separating the View Model responsibility into another class, and then setting the View's DataContext to an instance of that class, but the approach you have taken here works for simple cases.
I have a ListBox with several items on it (TextBlocks, Images and so on), what I'm trying to do is access an element by it's name at a specific ListBox index.
I know the element name and the index i need to access, in this case I need to change the visibility property of an image control to collapsed.
I've looked at a few examples using VisualTreeHelper here but they were only to access element by name, not by name and index, which is what i need to do but have not been able to.
Thanks, Bob.
I implemented a small demo to emphasize data binding using MVVM patern.
In this example I toggle the TextBlock visibility using ShowTextbox property bound to the TextBlock.Visibility by un/checking the Checkbox.
App.xaml.cs
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
var mainViewModel = new MainViewModel
{
ListItems = new ObservableCollection<MyModel>
{
new MyModel
{
MyPropertyText = "hello",
ShowText = true,
ShowTextbox = Visibility.Visible
}
}
};
var app = new MainWindow() {DataContext = mainViewModel};
app.Show();
}
}
MainWindow.xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfApplication1="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ListBox HorizontalAlignment="Left" Height="148" VerticalAlignment="Top" Width="299" Margin="30,57,0,0" ItemsSource="{Binding Path=ListItems}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Path=MyPropertyText}" Visibility="{Binding Path=ShowTextbox}"/>
<CheckBox IsChecked="{Binding ShowText}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
MainWindow.cs
public partial class MainWindow : Window
{
private MainViewModel _mainViewModel;
public MainWindow()
{
InitializeComponent();
}
}
MainViewModel.cs
public class MainViewModel : ObservableObject
{
public ObservableCollection<MyModel> ListItems
{
get { return _listItems; }
set
{
_listItems = value;
RaisePropertyChanged("ListItems");
}
}
}
MyModel.cs
public class MyModel : ObservableObject
{
private string _myPropertyText;
private bool _showText;
private Visibility _showTextbox;
public string MyPropertyText
{
get { return _myPropertyText; }
set
{
_myPropertyText = value;
RaisePropertyChanged("MyPropertyText");
}
}
public bool ShowText
{
get { return _showText; }
set
{
_showText = value;
RaisePropertyChanged("ShowText");
ShowTextbox = value ? Visibility.Visible : Visibility.Collapsed;
}
}
public Visibility ShowTextbox
{
get { return _showTextbox; }
set
{
_showTextbox = value;
RaisePropertyChanged("ShowTextbox");
}
}
}
ObservableObject.cs
public class ObservableObject : INotifyPropertyChanged
{
#region Constructor
public ObservableObject() { }
#endregion // Constructor
#region RaisePropertyChanged
/// <summary>
/// Raises this object's PropertyChanged event.
/// </summary>
/// <param name="propertyName">The property that has a new value.</param>
protected virtual void RaisePropertyChanged(string propertyName = "")
{
VerifyPropertyName(propertyName);
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
#endregion
#region Debugging Aides
/// <summary>
/// Warns the developer if this object does not have
/// a public property with the specified name. This
/// method does not exist in a Release build.
/// </summary>
[Conditional("DEBUG")]
[DebuggerStepThrough]
public void VerifyPropertyName(string propertyName)
{
// If you raise PropertyChanged and do not specify a property name,
// all properties on the object are considered to be changed by the binding system.
if (String.IsNullOrEmpty(propertyName))
return;
// Verify that the property name matches a real,
// public, instance property on this object.
if (TypeDescriptor.GetProperties(this)[propertyName] == null)
{
string msg = "Invalid property name: " + propertyName;
if (this.ThrowOnInvalidPropertyName)
throw new ArgumentException(msg);
else
Debug.Fail(msg);
}
}
/// <summary>
/// Returns whether an exception is thrown, or if a Debug.Fail() is used
/// when an invalid property name is passed to the VerifyPropertyName method.
/// The default value is false, but subclasses used by unit tests might
/// override this property's getter to return true.
/// </summary>
protected virtual bool ThrowOnInvalidPropertyName { get; private set; }
#endregion // Debugging Aides
#region INotifyPropertyChanged Members
/// <summary>
/// Raised when a property on this object has a new value.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
#endregion // INotifyPropertyChanged Members
}
I ended up going about it in a slightly different way, based on the example found here and using the elements' tag property instead, just changing the element from a TextBlock to an Image
This way i could bind the element Tag, and use that later on do target the needed items.
private void SearchVisualTree(DependencyObject targetElement, string _imageTag)
{
var count = VisualTreeHelper.GetChildrenCount(targetElement);
if (count == 0)
return;
for (int i = 0; i < count; i++)
{
var child = VisualTreeHelper.GetChild(targetElement, i);
if (child is Image)
{
Image targetItem = (Image)child;
if (targetItem.Tag as string == _imageTag && targetItem.Visibility == Visibility.Visible)
{
targetItem.Visibility = Visibility.Collapsed;
return;
}
}
else
{
SearchVisualTree(child, _imageTag);
}
}
}
Hopefully this helps someone else in the future...
Ive been playing with wpf and 2 way data binding to better understand it and ive noticed that when a textbox has 2 way data binding to a property the property is called twice. I have verified this by writing a value to the output window when the property is called. My code is below:-
My xaml
<Page
x:Class="_2waybindTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:_2waybindTest"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<TextBox HorizontalAlignment="Left" Margin="55,93,0,0" TextWrapping="Wrap" Text="{Binding TestProperty, Mode=TwoWay}" VerticalAlignment="Top" Width="540"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="55,31,0,0" VerticalAlignment="Top" Click="Button_Click_1"/>
<TextBox HorizontalAlignment="Left" Margin="55,154,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="540"/>
</Grid>
</Page>
my simple viewmodel class to test
public class viewmodel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string _TestProperty;
public void SetTestProperty()
{
this.TestProperty = "Set Test Property";
}
public string TestProperty{
get
{
return this._TestProperty;
}
set
{
this._TestProperty = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("TestProperty"));
}
Debug.WriteLine("this._TestProperty = " + this._TestProperty);
}
}
}
my xaml code behind
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
DataContext = new viewmodel();
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached. The Parameter
/// property is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
var vm = (viewmodel)DataContext;
vm.SetTestProperty();
}
}
Why is it called twice. Is this expected behaviour?
Generally, you should check if value actually changed, before firing a propertyChanged event, otherwise you may get into infinte cycle of binding updates. In your case, textbox is probably checking for change, preventing such cycle.
public string TestProperty{
set
{
if(this._TestProperty == value)
{
return;
}
this._TestProperty = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("TestProperty"));
}
}
}
I am new in WPF. I used to work in Winforms.
In Winforms I had the DataGridView that allows me to change, when I want a cell value.
Simply using:
dataGridView[columnIndex, rowIndex].Value = "New Value";
It works.
How can I accomplish this using DataGrid from WPF?
I was looking thorught stack over flow and could figure out an easy way to do this.
Thank you
Ok the simplest way to handle DataGrid is by binding to an ItemSource.
The example below shows how to bind your list and how changes upadte the DataGrid.
public partial class MainWindow : Window
{
private ObservableCollection<ConnectionItem> _connectionitems = new ObservableCollection<ConnectionItem>();
public MainWindow()
{
InitializeComponent();
ConnectionItems.Add(new ConnectionItem { Name = "Item1", Ping = "150ms" });
ConnectionItems.Add(new ConnectionItem { Name = "Item2", Ping = "122ms" });
}
public ObservableCollection<ConnectionItem> ConnectionItems
{
get { return _connectionitems; }
set { _connectionitems = value; }
}
private void button1_Click(object sender, RoutedEventArgs e)
{
// to change a value jus find the item you want in the list and change it
// because your ConnectionItem class implements INotifyPropertyChanged
// ite will automaticly update the dataGrid
// Example
ConnectionItems[0].Ping = "new ping :)";
}
}
public class ConnectionItem : INotifyPropertyChanged
{
private string _name;
private string _ping;
public string Name
{
get { return _name; }
set { _name = value; NotifyPropertyChanged("Name"); }
}
public string Ping
{
get { return _ping; }
set { _ping = value; NotifyPropertyChanged("Ping"); }
}
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Notifies the property changed.
/// </summary>
/// <param name="property">The info.</param>
public void NotifyPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
Xaml:
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication4"
xmlns:properties="clr-namespace:WpfApplication4.Properties"
Title="MainWindow" Height="300" Width="400" Name="UI" >
<Grid>
<DataGrid Name="dataGridView" ItemsSource="{Binding ElementName=UI,Path=ConnectionItems}" Margin="0,0,0,40" />
<Button Content="Change" Height="23" HorizontalAlignment="Left" Margin="5,0,0,12" Name="button1" VerticalAlignment="Bottom" Width="75" Click="button1_Click" />
</Grid>
</Window>
i added a button to show how the data updates when you change something in your list, The class ConnectionItem is where you will store all your info for the datagrid.
Hope this helps