One issue that raises its head every now and again is how to add controls to a List’s Data Template in such a way that you can understand what data item the control is associated with when the control raises an event. E.g. I want to know what data item I should remove from a list when the user de-selects a checkbox;
<DataTemplate x:Key="MyDataClassItemTemplate"> <StackPanel> <CheckBox IsChecked="{Binding IsSelected, Mode=TwoWay}" Content="{Binding DisplayName}" Unchecked="CheckBox_Unchecked" /> </StackPanel> </DataTemplate>
As you can see the checkbox has an Unchecked event but when that fires you will only be told what specific instance of the checkbox raised the event, not what the associated data item is. Previously I have worked-around this issue using the Visual Tree but I’ve always hated that solution. So I’m now using the following code that relies on the fact that my control has some form of data binding;
private MyDataClass MyDataClassFromCheckBox(object sender) { FrameworkElement fe = sender as FrameworkElement; BindingExpression be = fe.GetBindingExpression(CheckBox.IsCheckedProperty); MyDataClass selectedMyDataClass = be.DataItem as MyDataClass; return selectedMyDataClass; }
There, a much nicer solution. Note the ‘IsCheckedProperty’, this would need to be changed depending upon the property you are using in the binding – it is easy to pass that in as a dependancy property argument. Another quick point, previously I’ve had a similar problem using a Button in a template. However, the button only had a fixed caption so there was no binding expression to use. One simple trick here is to create a fixed property in your view model and bind to that, e.g. myViewModel.ButtonCaption { get {return “My Button Caption” }}. Yes it’s a slight overhead but you may prefer that to using the visual tree, I do.
