Two dynamically assigned ContentControls in single view in Caliburn.Micro - silverlight

I have a UserControl that contains two ContentControls that need to have different UserControl Views bound to them at runtime. The attached-Property solution noted here does not seem to work in Silverlight. Or, I am doing something wrong. I also, found this, but it did not bring any joy either.
I had a single ContentControl working by naming it 'ActiveItem'. But, of course, I cannot have two ContentControls with the same name.
Thanks in advance for any help,
Jim

Just expose two public properties on your main view model, each one being an instance of the type of view model you wish to display. Then, in your view have a ContentControl with the corresponding name. E.g:
public class MyMainViewModel
{
private NavigationViewModel navigation;
private MyContentViewModel main;
public MyMainViewModel()
{
// better to inject factories using constructor injection here
this.Navigation = new NavigationViewModel();
this.Main = new MyContentViewModel();
}
public NavigationViewModel Navigation
{
get { return navigation; }
set { navigation= value; NotifyOfPropertyChanged(() => this.Navigation); }
}
public MyContentViewModel Main
{
get { return main; }
set { main= value; NotifyOfPropertyChanged(() => this.Main); }
}
...
}
<ContentControl x:Name="Navigation" />
...
<ContentControl x:Name="Main" />

This is an old question, but in case anyone is having the same issue, I post here my way of handling it from the beginning and in a more thorough manner:
Your main window that contain both (or even more than two) of your User Controls must be inherited from Caliburn.Micro.Conductor<Screen>.Collection.AllActive;
Your User Controls must be inherited from Caliburn.Micro.Screen;
You must also keep naming conventions in mind. If you use MenuUC as the name of a ContentControl in your View, also create a property named MenuUC in your ViewModel;
Initialize your UserControl as I do in Constructor;
Now you can use ActivateItem(MenuUC) and DeactivateItem(MenuUC) everywhere in your code. Caliburn.Micro automatically detects which one you want to work with.
Example XAML View code:
<Window x:Class="YourProject.Views.YourView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="YourViewTitle" Width="900" Height="480">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="4*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Menu Side Bar -->
<ContentControl Grid.Row="0" Grid.Column="0" x:Name="MenuUC" />
<!-- Panel -->
<Border Grid.Column="1" Grid.RowSpan="2" BorderThickness="1,0,0,0" BorderBrush="#FF707070" >
<ContentControl x:Name="PanelUC" />
</Border>
</Grid>
</Window>
Example C# ViewModel code:
class YourViewModel : Conductor<Screen>.Collection.AllActive
{
// Menu Side Bar
private MenuUCViewModel _menuUC;
public MenuUCViewModel MenuUC
{
get { return _menuUC; }
set { _menuUC = value; NotifyOfPropertyChange(() => MenuUC); }
}
// Panel
private Screen _panelUC;
public Screen PanelUC
{
get { return _panelUC; }
set { _panelUC = value; NotifyOfPropertyChange(() => PanelUC); }
}
// Constructor
public YourViewModel()
{
MenuUC = new MenuUCViewModel();
ActivateItem(MenuUC);
PanelUC = new FirstPanelUCViewModel();
ActivateItem(PanelUC);
}
// Some method that changes PanelUC (previously FirstPanelUCViewModel) to SecondPanelUCViewModel
public void ChangePanels()
{
DeactivateItem(PanelUC);
PanelUC = new SecondPanelUCViewModel();
ActivateItem(PanelUC);
}
}
In the above example, ChangePanels() acts as a method to load new User Control into your ContentControl.
Also read this question, it might be help you further.

Related

Properties don't update front-end when written within ICommand-tied function

UPDATE 3
" I want that the text from this TextBox should be shown in another TextBox(in another view)"
The second textbox in another view is meant to show other information that is tied to the first textbox, but not the copy.
So the user control contains a text box for, say, Bus code. Once I enter bus code, tabbing out will trigger a fetch from the database for other details such as bus name, bus destination, bus model etc.
The others textbox which is in another view then displays the bus name. All following textboxes display destination and so forth. When the command is invoked, and I try to write to the property BusName, it gets assigned (and I call Notify("BusName")) but it does not show on the UI.
Hope that was more clear. Sorry for any confusion caused :).
UPDATE2 - Response to blindmeis
Thanks for your reply though this not appear to be what I was looking for. The tab out is essential because that is how management wants their pages to be populated i.e. when you tab out of a 'code' textbox after entering the code, it will use the code to fetch data from the db to populate the rest of the controls. This does not appear to have the tab-out behavior in it. As for the 3rd dependency property, it is in my original code, I simply did not include it here because the value in the first textbox (user control tabout textbox) is not relevant to the problem. Simply, what I am trying to accomplish is that the second textbox must populate when you tab-out of the first textbox.
I could do this with an eventhandler, but wanted to use commands. I am thinking now perhaps commands are not the way to go here and I should switch to using an event handler.
Please advise if you still have any ideas on how to get the second textbox to populate when you tab out of the first (by putting a breakpoint in populate, you will see that the property gets assigned. ). If I have not understood correctly or missed something here, please let me know. Thanks!
UPDATE!
I have created a VS2013 solution mimicking my code, which reproduces the problem. It is at this public google drive link as a zip file (takes a few seconds for the download icon to appear):
https://drive.google.com/file/d/0B89vOvsI7Ubdbk85SVlvT3U2dVU/view?usp=sharing
You will see that the 2nd text box does not update despite the bound property storing the new value.
Greatly appreciate any help. Thanks in advance.
Original post:
I have a textbox control to which I have tied a key binding based command to go process some actions (in a method that the command has been tied to) when the user hits tab while in the textbox (tabs out).
I have other controls in that page that are boiund to properties in the viewmodel that I write to in that tab-out connected function. When I write my properties in the constructor or somewhere 'outside' that command invokation they seem to work fine and the values show on the page, but when I write them within that command invocation, the properties in the vm contain the values but don't show up on the UI
Any ideas why and how to fix?
Thanks much in advance
From XAML:
<TextBox Name="txtCode" Text="{Binding Path=CodeValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<TextBox.InputBindings>
<KeyBinding Key="Tab" Command="{Binding RetrieveRecordCmd}" > </KeyBinding>
</TextBox.InputBindings>
</TextBox>
From VM:
RetrieveRecordCmd = new GSSCommand(RetrieveRecord, param => this.CanExecuteRetrieveRecordCmd);
Command tied function:
public void RetrieveRecord(object obj)
{
objPie = null;
//Check if a record exists for that code
gssSvcMethodStatusBase = gssSvcClientBase.ReadPies(ref gssSvcGlobalVarsBase, out objPie, out grfaBase, CodeValue);
if ((objPie != null)) // && (objPie.DateCreated > DateTime.MinValue))
PopulatePage(objPie);
else if (objPie == null)
InitiateCreateNew();
else
return;
}
It looks like you have implemented the INotifyPropertyChanged interface in the strict sense, but are missing the actual functionality. The interface itself doesn't automatically give you change notifications. You also need to fire the PropertyChanged event when each property changes. The standard pattern looks like:
private string _name;
public string Name
{
get { return _name; }
set
{
if (_name == value)
return;
_name = value;
NotifyPropertyChanged("Name");
}
}
You should make a habit of writing all mutable properties which you intend to bind to the UI in this format. Snippets can make this easier to do consistently.
this works, but i dont know if this is the behavior you want.
<UserControl x:Class="ProblemDemoWPF.TextBoxTabOutUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
Name="TabOutTextUserControl"
>
<StackPanel Margin="0,0,0,0" Orientation="Horizontal">
<Label Content="UserControl (ucTextBox)->"></Label>
<TextBox Width="80" Height="30" BorderBrush="Black"
BorderThickness="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="{Binding ElementName=TabOutTextUserControl, Path=CodeValue}">
</TextBox>
</StackPanel>
</UserControl>
new Dependency Propertie with right binding without DataContext
public partial class TextBoxTabOutUserControl : UserControl
{
public static readonly DependencyProperty CodeValueProperty =
DependencyProperty.Register("CodeValue", typeof(string), typeof(TextBoxTabOutUserControl));
public string CodeValue
{
get { return (string)GetValue(CodeValueProperty); }
set { SetValue(CodeValueProperty, value); }
}
public TextBoxTabOutUserControl()
{
InitializeComponent();
}
}
Just bind both to LocTextBoxText
<Window x:Class="ProblemDemoWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:loc="clr-namespace:ProblemDemoWPF"
Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<loc:TextBoxTabOutUserControl Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" HorizontalAlignment="left"
CodeValue="{Binding Buscode, Mode=OneWayToSource}"/>
<Label Content="Busname" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Left"></Label>
<TextBox Width="100" Grid.Row="1" Grid.Column="1" Text="{Binding Path=Busname, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBox>
<Label Content="Busdestination" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Left"></Label>
<TextBox Width="100" Grid.Row="2" Grid.Column="1" Text="{Binding Path=Busdestination, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBox>
<Label Content="Busmodel" Grid.Row="3" Grid.Column="0" HorizontalAlignment="Left"></Label>
<TextBox Width="100" Grid.Row="3" Grid.Column="1" Text="{Binding Path=Busmodel, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"></TextBox>
</Grid>
</Window>
add Notify to property setter
class MainWindowViewModel : INotifyPropertyChanged
{
private String _buscode;
private string _busname;
private string _busdestination;
private string _busmodel;
public String Buscode
{
get
{
return _buscode;
}
set
{
if (_buscode != value)
{
_buscode = value;
Notify("Buscode");
FetchData(_buscode);
}
}
}
private void FetchData(string buscode)
{
//DB stuff
this.Busname = "Name 1234";
this.Busmodel = "Model 1234";
this.Busdestination = "Destination 1234";
}
public string Busname
{
get { return _busname; }
set { _busname = value; Notify("Busname"); }
}
public string Busdestination
{
get { return _busdestination; }
set { _busdestination = value; Notify("Busdestination"); }
}
public string Busmodel
{
get { return _busmodel; }
set { _busmodel = value; Notify("Busmodel"); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected void Notify(string propertyName)
{
if (this.PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}

Can't access a wpf control from an outside class

I want to call a label control on my main window from an outside class. But the class doesn't recognize it.
My file structure is like this
ZoomBorder.cs
MainWindow.xaml
XAML:
<Window x:Class="GUI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PanAndZoom"
Title="PanAndZoom" Height="600" Width="900" WindowStartupLocation="CenterScreen">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="100"></RowDefinition>
</Grid.RowDefinitions>
<local:ZoomBorder x:Name="border" ClipToBounds="True" Background="Gray">
<!--<Image Source="/GUI;component/Images/Desert.jpg"/>-->
<Canvas Width="300" Height="300" Background="Green"></Canvas>
</local:ZoomBorder>
<StackPanel Grid.Row="1">
<Label x:Name="pos" x:FieldModifier="public">Position</Label>
</StackPanel>
</Grid>
</Window>
ZoomBorder.cs:
public class ZoomBorder : Border
{
...
private void SomeMethod()
{
// this doesn't work!
pos.Content = "This label is changed by ZoomBorder!";
}
}
The way you tried is only works if the property defined in the same class :
pos.Content = "This label is changed by ZoomBorder!";
In case of static property from other class, you can access it this way :
MainWindow.pos = ....
//or generally
ClassName.PropertyName = ....
Unfortunately UI controls in your XAML isn't static property. In case of non static property from other class, you need class instance to access the property :
MainWindow mainWindowInstance = new MainWindow();
mainWindowInstance.pos = ....
Snippet above is only example, in your case you'll need to find a way to pass current MainWindow instance displayed to ZoomBorder instead of creating new instance as this example demonstrates.
There's no reason for it to work. What you're trying to do is pretty much equivalent to :
class Parent // = MainWindow
{
object xxx;
Child child;
}
class Child // = ZoomBorder
{
void SomeFunction()
{
this.xxx = ...; // Doesn't work, the class Child doesn't have any xxx field
}
}
This should work.
var wnd = Application.Current.MainWindow as MainWindow;
var label = wnd.pos;

Adding Caliburn Micro Screen(UserControl) to a Canvas in WPF MVVM?

I am using Caliburn Micro in my Project and i have many UserControls and thier viewmodel inherited from PropertyChangedBase, i want this UserControl to be added to a Canvas in my ShellView. I dont want to use IWindowManager from showing Windows instead i want them to get added in a Canvas.
Please help. How can i do that.
If you use ContentControl within your ShellView you can hook into the View-ViewModel binding process of Caliburn.Micro.
I assume that in your ShellViewModel you have a bunch of properties exposed that are types of ViewModel. If you place a ContentControl in your ShellView (this could be on/as a child of Canvas if that is the container you wish to use to layout your Shell), and then name that control with the name of the property in your ShellViewModel you wish it to be bound to, then Caliburn's ViewModelBinder will do the rest for you.
As an example say you have a VM called FizzViewModel and a matching View called FizzView (which is just a UserControl) and you want FizzView to appear on your ShellView you could do something like the following...
A stripped back ShellViewModel
public class ShellViewModel : Screen, IShell
{
public ShellViewModel(FizzViewModel theFizz)
{
TheFizz = theFizz;
}
public FizzViewModel TheFizz { get; set; }
}
And its matching ShellView
<UserControl x:Class="ANamespace.ShellView">
<Canvas>
<ContentControl x:Name="TheFizz"></ContentControl>
</Canvas>
</UserControl>
Here because the ContentControl is named TheFizz, it will be bound by Caliburn to the property with that name on your VM (the one of type FizzViewModel)
Doing this means you don't have to laydown your UserControl's using their true types on your ShellView, you let Caliburn do the work for you via conventions (which all so means its easy to swap out the type TheFizz if you just add a little more interface indirection).
UPDATE
From the extra information you have provided in the comments, I can now see you are actually looking at a problem that requires an ItemsControl.
The default DataTemplate Caliburn uses looks like the following
<DataTemplate xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro">
<ContentControl cal:View.Model="{Binding}"
VerticalContentAlignment="Stretch"
HorizontalContentAlignment="Stretch" />
</DataTemplate>
You will notice that it uses a ContentControl, which has some advantages as I have discussed above. Basically what this will do is allow Caliburn to provide DataTemplateSelector like behaviour to the items in your ItemsControl. So you can add VMs of different types to the collection your ItemsControl is bound to and this default DataTemplate will resolve the type of View to use to display it. The following demos a very simple example of how you can achieve what you want.
First the ShellViewModel, take note of the BindableCollection named Items
[Export(typeof(IShell))]
public class ShellViewModel : IShell
{
public ShellViewModel()
{
Items = new BindableCollection<Screen>();
_rand = new Random();
}
public BindableCollection<Screen> Items { get; set; }
private Random _rand;
public void AddItem()
{
var next = _rand.Next(3);
var mPosition = System.Windows.Input.Mouse.GetPosition(App.Current.MainWindow);
switch (next)
{
case 0:
{
Items.Add(new BlueViewModel
{
X = mPosition.X,
Y = mPosition.Y,
});
break;
}
case 1:
{
Items.Add(new RedViewModel
{
X = mPosition.X,
Y = mPosition.Y,
});
break;
}
case 2:
{
Items.Add(new GreenViewModel
{
X = mPosition.X,
Y = mPosition.Y,
});
break;
}
default:
break;
}
}
}
And then a few dummy VM types that you want to display in your Shell. These could be/do anything you like:
public abstract class SquareViewModel : Screen
{
public double X { get; set; }
public double Y { get; set; }
}
public class BlueViewModel : SquareViewModel
{
}
public class RedViewModel : SquareViewModel
{
}
public class GreenViewModel : SquareViewModel
{
}
Now a ShellView, note the ItemsControl which binds to the Items property on your ShellViewModel
<Window x:Class="WpfApplication2.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro">
<Grid >
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<ItemsControl x:Name="Items"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas cal:Message.Attach="[Event MouseLeftButtonUp] = [Action AddItem()]"
Background="Transparent"></Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left" Value="{Binding Path=X}" />
<Setter Property="Canvas.Top" Value="{Binding Path=Y}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Grid>
</Window>
And an example of a UserControl that will be used to display the GreenViewModel, create 2 more of these, changing the names to RedView and BlueView and set the backgrounds appropriately to get the demo to work.
<UserControl x:Class="WpfApplication2.GreenView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="30"
Height="30">
<Grid Background="Green"></Grid>
</UserControl>
What this example does when put together is creates colored squares on the Canvas of your shell based on the location of the mouse click. I think you should be able to take this and extend it to your needs.

Selection States in MapItemsControl of Bing Map Silverlight control

I am new to silverlight and hence new to Bing Map Control as well.
Here's what i am trying to achieve
I've a viewmodel which has 2 properties and looks like this...
public class Vm : INotifyPropertyChanged
{
private LocationCollection _locations;
public LocationCollection Locations
{
get { return _locations; }
set
{
_locations = value;
this.Notify("Locations");
}
}
private Location _selectedLocation;
public Location SelectedLocation
{
get { return _selectedLocation; }
set
{
_selectedLocation = value;
this.Notify("SelectedLocation");
}
}
protected virtual void Notify(string property)
{
if( null != this.PropertyChanged)
{
PropertyChangedEventArgs e = new PropertyChangedEventArgs(property);
this.PropertyChanged(this,e);
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
In my XAML I have a listbox and a Bing Map control. The listbox is bound to locations (Display member is a Latitude for now) and the map control has a MapsItemControl which is bound to Locations as well.
The SelectedItem of ListBox is bound to SelectedLocation and The Center of the map is bound to SelectedLocation as well. So the xaml looks like this
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListBox ItemsSource="{Binding Path=Locations}"
SelectedItem="{Binding Path=SelectedLocation, Mode=TwoWay}"
DisplayMemberPath="Latitude"
Grid.Row="0"/>
<map:Map
Grid.Row="1"
CredentialsProvider="Av2K1aKwZLPJRS-F_m1TGlFg2bPFVVDgMGbxfFp-1rdpUrwfQmiPSouaSHrHoK-j"
Loaded="Map_Loaded"
Center="{Binding Path=SelectedLocation, Mode=TwoWay}"
ZoomLevel="17">
<map:MapItemsControl x:Name="mapItemsControl" ItemsSource="{Binding Path=Locations}">
<map:MapItemsControl.ItemTemplate>
<DataTemplate>
<map:Pushpin
Location="{Binding}"
/>
</DataTemplate>
</map:MapItemsControl.ItemTemplate>
</map:MapItemsControl>
</map:Map>
</Grid>
As i select the items in the listbox i am able to see that the center of the map changes. However i want to change the Template of Pushpin in this case as well. Let's say that i want to display an image instead of the OOB Pushpin. I understand the concept of how to customize the pushpin however i am unable to get any selection states in MapsItemControl similar to what i can find in other ItemsControl like listbox etc.
Can someone help me on this ??
You could add another MapItemsControl that was bound to only your SelectedLocation and have the other MapItemsControl be bound to all the locations except the SelectedLocation.
That way you could have seperate templates for the selected ones and the unselected ones.

Generating grid dynamically in MVVM pattern

I am writing a WPF application where where i need to display custom file iformation which consists of field name & its value. I generate a grid rumtime with label & textboxes. I display the field name in label & field value in textbox(i want it to be editable). & each time file selection changes, number of field change & so the grid columns & rows. Right now I am generating this grid in code behind . Is there any way i can do it in XAml with view model.
This is pretty easy to do with an ItemsControl. If you ViewModel exposes a list of metadata objects, say a class like this:
public class FileMetaData : INotifyPropertyChanged
{
private string name;
private string value;
public event PropertyChangedEventHandler PropertyChanged = (o, e) => { };
public string Name
{
get { return name; }
set
{
name = value;
PropertyChanged(this, new PropertyChangedEventArgs("Name"));
}
}
public string Value
{
get { return value; }
set
{
this.value = value;
PropertyChanged(this, new PropertyChangedEventArgs("Value"));
}
}
}
Then, your ViewModel would expose it as an ObservableCollection (so WPF knows when new items are added or removed):
public class MyViewModel
{
...
public ObservableCollection<FileMetaData> Files { get; private set; }
...
}
Then, your view would use an ItemsControl with an ItemTemplate to display it:
<ItemsControl ItemsSource="{Binding Files}" Grid.IsSharedSizeScope="True">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="one" />
<ColumnDefinition Width="Auto" SharedSizeGroup="two" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" />
<TextBox Grid.Column="1" Text="{Binding Value}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Note that I'm setting Grid.IsSharedSizeScope to true on the ItemsControl, so the columns will align. If you have a lot of data, you'll probably want to wrap this in a ScrollViewer (or better retemplate the ItemsControl to have one).
I'm not sure why you're creating this grid at runtime. You should look into using a standard presentation method such as a <ListBox> with a custom item template. Always look to use declaritive definition of your UI (within the XAML) instead of the codebehind.
I've got a blog post on creating a checked listbox that shows some of the details, but you should be able to find other good examples out there as well.

Resources