How can I access my btnViewTable from code-behind? Specifically to be able to set the visibility on or off, or even remove it. I've looked at GetTemplateChild as well as FindName, but have been unable to access the button. I can manage to obtain a reference to the ControlTemplate, but can't get any further than that.
<Grid x:Name="pnlSearch" Background="White">
<TextBlock x:Name="txtSearchResults" />
<sdk:DataGrid x:Name="grdResults">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Binding="{Binding Value}"/>
<sdk:DataGridTextColumn Binding="{Binding FoundFieldName}"/>
</sdk:DataGrid.Columns>
<sdk:DataGrid.RowGroupHeaderStyles>
<Style TargetType="sdk:DataGridRowGroupHeader">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="sdk:DataGridRowGroupHeader">
<sdk:DataGridFrozenGrid Name="Root">
<StackPanel>
<Button x:Name="btnViewTable"
var button = (Button)DataGrid.Template.FindName("btnViewTable", "DataGridControl");
button.Click += //Do something;
Where DataGrid/DataGridControl is the actual DataGridControl
To handle parts of the template, from outside of the control, is always a not-so-good idea.
For a quick fix, I'd go with:
<Style TargetType="sdk:DataGridRowGroupHeader">
<Setter Property="Tag" Value="{Binding SomeVisibilityProperty}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="sdk:DataGridRowGroupHeader">
<Grid
<sdk:DataGridFrozenGrid Name="Root">
<StackPanel>
<Button x:Name="btnViewTable"
Visibility="{TemplateBinding Tag}"
Where SomeVisibilityProperty is a property in the data context. Might need to use RelativeSource.
For a "true" fix, I'd define an attached property. Set this property to bind to the same property on parent grid and then have the button to bind to the property on DataGridRowGroupHeader.
I ended up just referring to a property in codebehind:
http://www.jayway.com/2011/05/17/bind-from-xaml-to-property-defined-in-code-behind/
Related
I am trying to learn something about WPF and I am quite amazed by its flexibility.
However, I have hit a problem with Styles and DataTemplates, which is little bit confusing.
I have defined below test page to play around a bit with styles etc and found that the Styles defined in <Page.Resources> for Border and TextBlock are not applied in the DataTemplate, but Style for ProgressBar defined in exactly the same way is applied.
Source code (I just use Kaxaml and XamlPadX to view the result)
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<Style TargetType="{x:Type Border}">
<Setter Property="Background" Value="SkyBlue"/>
<Setter Property="BorderBrush" Value="Black"/>
<Setter Property="BorderThickness" Value="2"/>
<Setter Property="CornerRadius" Value="5"/>
</Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontWeight" Value="Bold"/>
</Style>
<Style TargetType="{x:Type ProgressBar}">
<Setter Property="Height" Value="10"/>
<Setter Property="Width" Value="100"/>
<Setter Property="Foreground" Value="Red"/>
</Style>
<XmlDataProvider x:Key="TestData" XPath="/TestData">
<x:XData>
<TestData xmlns="">
<TestElement>
<Name>Item 1</Name>
<Value>25</Value>
</TestElement>
<TestElement>
<Name>Item 2</Name>
<Value>50</Value>
</TestElement>
</TestData>
</x:XData>
</XmlDataProvider>
<HierarchicalDataTemplate DataType="TestElement">
<Border Height="45" Width="120" Margin="5,5">
<StackPanel Orientation="Vertical" Margin="5,5" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock HorizontalAlignment="Center" Text="{Binding XPath=Name}"/>
<ProgressBar Value="{Binding XPath=Value}"/>
</StackPanel>
</Border>
</HierarchicalDataTemplate>
</Page.Resources>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<StackPanel Orientation="Vertical" VerticalAlignment="Center">
<Border Height="45" Width="120" Margin="5,5">
<StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock HorizontalAlignment="Center" Text="Item 1"/>
<ProgressBar Value="25"/>
</StackPanel>
</Border>
<Border Height="45" Width="120" Margin="5,5">
<StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock HorizontalAlignment="Center" Text="Item 2"/>
<ProgressBar Value="50"/>
</StackPanel>
</Border>
</StackPanel>
<ListBox Margin="10,10" Width="140" ItemsSource="{Binding Source={StaticResource TestData}, XPath=TestElement}"/>
</StackPanel>
</Page>
I suspect it has something to do with default styles etc, but more puzzling is why some Styles are applied and some not. I cannot find an easy explanation for above anywhere and thus would like to ask if someone would be kind enough to explain this behaviour in lamens' terms with possible links to technical description, i.e. to MSDN or so.
Thanks in advance for you support!
I discovered a simple workaround for this. For any elements that are not able to search outside the data template encapsulation boundary (i.e. are not being implicitly styled), you can just declare an empty style within the data template for that element type and use the BasedOn attribute of the style to find the correct implicit style outside the data template to apply.
In the example below, the TextBox is able to search outside the data template encapsulation boundary (because it inherits from Control?), but the TextBlock is not able to, so I declare the empty style for it which can search outside the data template.
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataTemplate.Resources>
<Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}" />
</DataTemplate.Resources>
<DockPanel>
<TextBlock Text="{Binding Name}" />
<TextBox Text="{Binding Value}" />
</DockPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
This is actually by design. Elements that do not derive from Control will not pick up implicit Styles, unless they are in the application resources.
This link explains this in more detail, or you can view the Connent bug report.
I've looked into this also, and I personally think it's a bug. I've noticed that the style is set if you name your styles like so:
<Style x:Key="BorderStyle" TargetType="{x:Type Border}">
etc...
and explicitly set your DataTemplate to use those styles:
<HierarchicalDataTemplate DataTemplate="TestElement">
<Border Height="45" Width="120" Margin="5,5", Style="{StaticResource BorderStyle}">
I think that it's possible that for DataTemplates (and maybe ControlTemplates), they default to having a null style, unless you explicitly set them.
That to me is not meant to happen - it's not a logical way of WPF working...
This is because ListBox is a logical parent of your datatemplate items, now remember, all properties those are "inheritable" like font, forecolor etc, are derived from the logical parent and ListBox already overrides it in its own default style, thats why this will not work. However in this case, you can use named styles as Mr. Dave has suggested, but I think if it does not work then this is a known problem in case of List Box etc, you can refere to my question here, i had similar problem in listbox, and the answers in my question are in more detail.
We have a file of standard styles. One style, SectionGroup, we use on all our GroupBox elements. It has a custom template which uses a Border to put an underline below the header, among other things.
On one page, we have a checkbox next to a GroupBox header; when the user unchecks the checkbox, the contents of the GroupBox hide (visibility collapsed) and the header remains. Unfortunately the underline under the header then looks ugly; we also want to hide this.
I've given it my best attempt, so the parent SectionGroup style now looks like this:
<Style x:Key="SectionGroup" TargetType="GroupBox">
<Style.Resources>
<Thickness x:Key="HeaderBorderThickness">0,0,0,1</Thickness>
</Style.Resources>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="GroupBox">
<Grid Margin="0">
...
<Border Grid.Row="0" BorderThickness="{DynamicResource HeaderBorderThickness}" >
<TextBlock Text="{Binding Header, RelativeSource={RelativeSource AncestorType=GroupBox}}"/>
</Border>
...
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
By defining the HeaderBorderThickness resource and using it as a DynamicResource, I can override it in my page (as explained in this answer):
<GroupBox>
<GroupBox.Style>
<Style TargetType="GroupBox" BasedOn="{StaticResource SectionGroup}">
<Style.Resources>
<Thickness x:Key="HeaderBorderThickness">0,0,0,0</Thickness>
</Style.Resources>
<!-- TODO triggers here.. -->
</Style>
</GroupBox.Style>
<GroupBox.Header>Section One</GroupBox.Header>
...contents...
</GroupBox>
So indeed, by redefining a Thickness of the same key, the DynamicResource works as expected and there is no underline on the header.
Now I need to toggle it based on a trigger/binding. I'm pretty new to this, but elsewhere in this page I have figured out to do stuff like this:
<Grid Visibility="{Binding Path=FooBoolean, Converter={StaticResource BooleanToVisibility}}">
I think there's a little more magic involved in our viewmodel class (followed the example of existing bindings & properties), but it works.
Now the question is -- how do I bind the boolean value in FooBoolean, to the HeaderBorderThickness resource value? Or what other means can I use to accomplish my goal?
It seems to me that you could do this in a much more WPF way with a DataTrigger, perhaps something like this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding Header, RelativeSource={RelativeSource AncestorType=
GroupBox}}"/>
<Rectangle Grid.Row="1" Height="1" Margin="0,2,0,0" Fill="Black">
<Rectangle.Style>
<Style>
<Setter Property="Rectangle.Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{IsChecked, ElementName=YourCheckBox}"
Value="False">
<Setter Property="Rectangle.Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
</Grid>
This method enables you to set the Width, Height, Padding and whatever other properties of the line. If you can't access the CheckBox directly from the Style, then you could try adding a bool property to bind to both the Checkbox.IsChecked property and the DataTrigger.Binding property. Or just manage the Rectangle.Visibility in your own method.
I want to take the highlight background off of the radtreeview. I created a style to do this, but I keep getting errors and exceptions such as "Items collection must be empty." If I comment out the style the application works fine, so I know that it is the cause of the problem. I am fairly new to WPF, and I am sure I just don't understand how to use styles yet.
Thanks for your help. Here is the code.
<Grid x:Name="LayoutRoot" Background="Salmon">
<telerik:RadTreeView x:Name="radTreeView" Margin="8" ItemsSource="{Binding Errors}" Background="Salmon" Style="{StaticResource treeStyle}">
<Style TargetType="{x:Type telerik:RadTreeViewItem}" x:Name="treeStyle">
<Setter Property="Focusable" Value="False"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="{x:Null}"/>
<Setter Property="BorderBrush" Value="{x:Null}"/>
</Trigger>
</Style.Triggers>
</Style>
<telerik:RadTreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding SubItems}" >
<Grid Background="Salmon">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding Description}" IsHitTestVisible="False" />
<ListBox Grid.Row="1" ItemsSource="{Binding Messages}" Margin="20,0,0,0" BorderBrush="#00000000" BorderThickness="0" Background="Salmon" IsHitTestVisible="False" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Message}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</HierarchicalDataTemplate>
</telerik:RadTreeView.ItemTemplate>
</telerik:RadTreeView>
</Grid>
</UserControl>
If you know that this is not going to work, I was also trying to get rid of the highlight with the style code:
<Style TargetType="TreeViewItem">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#FFF"/>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="#000"/>
</Style.Resources>
</Style>
You get exceptions because your style tag is actually an item in the tree, and you have ItemsSource set.
Surround the style with <telerik:RadTreeView.ItemContainerStyle> tag.
This should solve the exception but it will not give you the result that you expect since the control template of the tree view item is actually showing another border that is not affected by the Background property. You will need to change the control template.
Telerik change the styles between releases, so giving you a template of a wrong version will probably won't help you.
But, you can go to the installation folder for Telerik and look for a folder called "Themes". There you'll find a solution with all the themes for telerik.
Choose the one that you use.
Find the resource dictionary for the tree view and copy the style and template for the item to your project.
Change xmlns definitions, make sure you have all the brushes and resources that the style depends upon.
Run to see that the style is ok.
In the template, find the VisualState with x:Name="MouseOver" and delete the storyboard inside it.
I've been asked to create a new control for a feature that we need, I'm really struggling on how to best achieve this in a generic and flexible way.
basically the control is very similar to a tree view, where as you would click on a node and then its children would then appear underneath that node.
for this control, they want it like this - when you click on a node, its children are then displayed on the left of parents container and so on.
I've done a quick (super quick) diagram in paint... (please don't laugh, its terrible! :) )
So you should just start with a single list of items and then progressive through the children of the selected item..
so my question is really, where do you start on something like this.. ? I'm fine with the data side but the XAML is the bit that's really confusing me, it needs to be very generic so it could potential cope with 100's of children panels
any help would be brilliant.
cheers.
ste.
If you are after a usercontrol and known bindings at designtime - it would be easy, but as a custom control - i'm very interested in good answers
like i said this can easy be done if you know the collection bindings and the childlevel. but its maybe a start to get a custom control.
<UserControl>
<UserControl.Resources>
<Style x:Key="{x:Type ListBox}" TargetType="{x:Type ListBox}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ListBoxItem">
<Setter Property="VerticalContentAlignment" Value="Stretch"></Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<UniformGrid Columns="1"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate DataType="{x:Type local:TreeItems}">
<Grid VerticalAlignment="Stretch">
<Border BorderBrush="Black" BorderThickness="1" >
<TextBlock Margin="5" Text="{Binding Name}"/>
</Border>
</Grid>
</DataTemplate>
</UserControl.Resources>
<StackPanel Orientation="Horizontal">
<ListBox x:Name="root" ItemsSource="{Binding}"></ListBox>
<ListBox x:Name="Lvl1" ItemsSource="{Binding ElementName=root, Path=SelectedItem.Childs}" />
<ListBox x:Name="Lvl2" ItemsSource="{Binding ElementName=Lvl1, Path=SelectedItem.Childs}" />
</StackPanel>
</UserControl>
This article from Josh Smith is a good starting point.
If all you need is a hierarchical data control, you better use a TreeView and not rolling your own control, as it is probably more complicated than you think (selection, keyboard navigation, etc.)
I have an application where I'm displaying UserControls in a GroupBox. To display the controls, I'm binding to a property in the ViewModel of the main form, which returns a ViewModel to be displayed. I've got DataTemplates set up so that the form automatically knows which UserControl/View to use to display each ViewModel.
When I display a different UserControl, I keep the ViewModel of the previous control active, but the Views are discarded automatically by WPF.
The problem that I'm having is that when the view shuts down, any two way bindings to the properties in the ViewModel are immediately set to null, and so when I display the ViewModel again all of the values are just set to null in the UI.
I assume this is because as part of the View closing down it disposes and clears any values in the controls it contains, and since the bindings are in place they propagate down to the ViewModel as well.
DataTemplates in my resources
<DataTemplate DataType="{x:Type vm:HomeViewModel}">
<vw:HomeView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:SettingsViewModel}">
<vw:SettingsView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:JobListViewModel}">
<vw:JobListView />
</DataTemplate>
Code used to display user controls
<GroupBox>
<ContentControl Content="{Binding Path=RightPanel}" />
</GroupBox>
Example of a control that I'm binding in one of the Views:
<ComboBox Name="SupervisorDropDown" ItemsSource="{Binding Path=Supervisors}" DisplayMemberPath="sgSupervisor"
SelectedValuePath="idSupervisor" SelectedValue="{Binding Path=SelectedSupervisorID}" />
and the relevant ViewModel properties:
public ObservableCollection<SupervisorsEntity> Supervisors
{
get
{
return supervisors;
}
}
public int? SelectedSupervisorID
{
get
{
return selectedSupervisorID;
}
set
{
selectedSupervisorID = value;
this.OnPropertyChanged("SelectedSupervisorID");
}
}
Any idea on how to stop my Views nulling the values in my ViewModels? I'm thinking that maybe I need to set the DataContext of the View to null before it closes down, but I'm not sure how to go about that with the way things are currently binding.
I've found one possible solution, but I really don't like it.
It turns out the DataContext IS being set to null already, but that doesn't help. It happens before the property is set to null. What appears to be happening is that the data bindings aren't being removed before the UserControl/View disposes of itself, and so the null value propagates down when the control is removed.
So when the DataContext changes, if the new context is null then I remove the relevant bindings on the ComboBox, as follows:
private void UserControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue == null)
{
SupervisorDropDown.ClearValue(ComboBox.SelectedValueProperty);
}
}
I'm not a big fan of this method, because it means I have to do remember to do it for every databound control I use. If there was a way I could just have every UserControl just remove their bindings automatically when they close that would be ok, but I can't think of any way to do that.
Another option might be to just restructure my app, so that the Views don't get destroyed until the ViewModels do - this would sidestep the problem entirely.
When I display a different
UserControl, I keep the ViewModel of
the previous control active, but the
Views are discarded automatically by
WPF.
The problem that I'm having is that
when the view shuts down, any two way
bindings to the properties in the
ViewModel are immediately set to null,
and so when I display the ViewModel
again all of the values are just set
to null in the UI.
I'm no expert on either WPF or MVVM, but something about this doesn't sound right. I have trouble believing that WPF disposal of the view is causing your problem. At the very least, in my limited experience I've never had anything like that happen. I suspect the culprit is either code in the view-model or the code swaping out which view-model is used for the datacontext.
After trying to stop the null setting by various means, I gave up and instead got it working as follows. I made the ViewModel read-only before closing its view. I accomplish this in my ViewModelBase class, where I added a IsReadOnly boolean property. Then in ViewModelBase.SetProperty() (see below) I ignore any property changes when IsReadOnly is true.
protected bool SetProperty<T>( ref T backingField, T value, string propertyName )
{
var change = !IsReadOnly && !EqualityComparer<T>.Default.Equals( backingField, value );
if ( change ) {
backingField = value;
OnPropertyChanged( propertyName );
}
return change;
}
It seems to be working like this, although I'd still love to know a better solution.
I had the same problem. What worked for me was removing UpdateSourceTrigger=PropertyChanged from my SelectedValueBindings. PropertyChanged UpdateSourceTriggers seem to fire on bound properties of closing views when you use that pattern:
<!--Users DataGrid-->
<DataGrid Grid.Row="0" ItemsSource="{Binding DealsUsersViewSource.View}"
AutoGenerateColumns="False" CanUserAddRows="True" CanUserDeleteRows="False"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<DataGrid.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}" Color="#FFC5D6FB"/>
</DataGrid.Resources>
<DataGrid.Columns>
<!--Username Column-->
<DataGridComboBoxColumn
SelectedValueBinding="{Binding Username}" Header="Username" Width="*">
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding DataContext.DealsUsersCollection.ViewModels,
RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
<Setter Property="SelectedValuePath" Value="Username"/>
<Setter Property="DisplayMemberPath" Value="Username"/>
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding DataContext.BpcsUsers,
RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
<Setter Property="SelectedValuePath" Value="Description"/>
<Setter Property="DisplayMemberPath" Value="Description"/>
<Setter Property="IsEditable" Value="True"/>
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
<!--Supervisor Column-->
<DataGridComboBoxColumn
SelectedValueBinding="{Binding Supervisor}" Header="Supervisor" Width="*">
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding DataContext.DealsUsersCollection.ViewModels,
RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
<Setter Property="SelectedValuePath" Value="Username"/>
<Setter Property="DisplayMemberPath" Value="Username"/>
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="ItemsSource" Value="{Binding DataContext.BpcsUsers,
RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
<Setter Property="SelectedValuePath" Value="Description"/>
<Setter Property="DisplayMemberPath" Value="Description"/>
<Setter Property="IsEditable" Value="True"/>
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
<!--Plan Moderator Column-->
<DataGridCheckBoxColumn Binding="{Binding IsPlanModerator}" Header="Plan Moderator?" Width="*"/>
<!--Planner Column-->
<DataGridCheckBoxColumn Binding="{Binding IsPlanner}" Header="Planner?" Width="*"/>
</DataGrid.Columns>
</DataGrid>
Container View:
<!--Pre-defined custom styles-->
<a:BaseView.Resources>
<DataTemplate DataType="{x:Type vm:WelcomeTabViewModel}">
<uc:WelcomeTabView/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:UserSecurityViewModel}">
<uc:UserSecurityView/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:PackItemRegisterViewModel}">
<uc:PackItemsRegisterView/>
</DataTemplate>
</a:BaseView.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<TabPanel Grid.Column="1" Grid.Row="1">
<TabControl TabStripPlacement="Top" ItemsSource="{Binding TabCollection}" SelectedIndex="{Binding SelectedTabIndex}"
DisplayMemberPath="DisplayName" MinWidth="640" MinHeight="480"/>
</TabPanel>
</Grid>
Container ViewModel:
TabCollection.Add(new WelcomeTabViewModel());
TabCollection.Add(new UserSecurityViewModel(_userService, _bpcsUsersLookup));
TabCollection.Add(new PackItemRegisterViewModel(_packItemService, _itemClassLookup));
SelectedTabIndex = 0;
Set the UpdateSourceTrigger explicit to LostFocus
If the view is closing and sets its data to null, it has no effect on your data in the viewmodel.
<ComboBox Name="SupervisorDropDown" ItemsSource="{Binding Path=Supervisors}" DisplayMemberPath="sgSupervisor"
SelectedValuePath="idSupervisor"
SelectedValue="{Binding Path=SelectedSupervisorID, UpdateSourceTrigger=LostFocus}" />