I am new to WPF and struggling to get tooltips working on disabled controls.
I have a list of Commands built "behind the scenes" in code. These commands are associated with radio buttons, rendered as toggle buttons using a resource template that defines the styles. The functionality works fine, as does the display, save for one piece:
I need to display to the user, only when the button is disabled, a tool tip.
I cannot seem to get the tooltips to display on disabled buttons. I have tried setting ToolTipService.ShowOnDisabled "true" everywhere I can think to try, and made sure IsHitTestVisible is "true", but nothing seems to work. Of course, a simple test using a disabled button on a window works fine - I am assuming something in the complexity of the rendering is causing my "show on disabled" not to be associated with the right part of the tree.
I have simplified things to remove the triggers related to enabling and disabling the tool tips based on the enable state of the buttons. At this point, I believe if I can get the tool tips showing on the disabled buttons, I will be able to implement the rest. But I sure do need help getting the tool tips to display when the buttons are disabled.
This is the relevant part of my Resource XAML.
This snip defines the radio buttons themselves and their binding :
<DataTemplate x:Key="CommandsTemplate" >
<ItemsControl IsTabStop="False" ItemsSource="{Binding}" Margin="0,10,0,0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Margin="0,2" >
<RadioButton
GroupName="CommandList"
Command="{Binding Path=Command}"
IsChecked="{Binding Path=IsChecked}"
Content="{Binding Path=DisplayName}"
IsEnabled="{Binding Path=Command.CanExecute}"
Style="{StaticResource CommandButtonStyle}"
>
</RadioButton >
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
This snip defines the command buttons layout itself. Obviously the tool tip here is setup to display on enabled buttons as well as disabled, but if I can get them displaying on the disabled ones, I'll be able to take it from there :
<Style x:Key="CommandButtonStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}" >
<Border
x:Name="border"
Padding="0,0,0,0"
CornerRadius="1,1,1,1"
Background="#cfd2d6"
SnapsToDevicePixels="True"
MinWidth="170"
MinHeight="35"
IsHitTestVisible="True"
ToolTipService.ShowOnDisabled="True"
ToolTip="This is a tool tip I want to see."
>
<ContentPresenter x:Name="contentPresenter"
VerticalAlignment="Center"
HorizontalAlignment="Center"
/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Background" TargetName="border" Value="#003f73"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="#ecf0f3"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I really appreciate the help - I use stack overflow constantly and have learned so much, but never before have I just hit a complete dead end. I don't know what else to try. So, I thought I would ask. Thank you --
EDIT: I have uploaded code showing the problem to GitHub. You can see the remains of Dev Hedgehogs code in it; I started with his working example and added to it until the problem reoccurred. The issue started when I added the inner ItemsControl back in to accommodate the more elaborate view model.
The code is in a zip file -- ToolTipTester.Zip. I hope that is ok. The Zip contains the full project.
https://github.com/Bearjing/TooltipTestApp/tree/657eb910df6654e61a3228958bc5e854c808e70e
It works all fine for me though I had to change your DataTemplate a little bit to fit my ViewModel. I didn't know how your ViewModel looked alike so I needed to create my own.
This is the ViewModel:
class MainWindowViewModel : INotifyPropertyChanged
{
private ObservableCollection<Person> employee;
public MainWindowViewModel()
{
this.Employee = new ObservableCollection<Person>();
this.Employee.Add(new Person { Name = "Test" });
}
public ObservableCollection<Person> Employee
{
get { return this.employee; }
set { this.employee = value; this.OnPropertyChanged("Employee"); }
}
...
This is XAML part:
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Window.Resources>
<Style x:Key="CommandButtonStyle" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}" >
<Border
x:Name="border"
Padding="0,0,0,0"
CornerRadius="1,1,1,1"
Background="#cfd2d6"
SnapsToDevicePixels="True"
MinWidth="170"
MinHeight="35"
IsHitTestVisible="True"
ToolTipService.ShowOnDisabled="True"
ToolTip="This is a tool tip I want to see.">
<ContentPresenter x:Name="contentPresenter"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Background" TargetName="border" Value="#003f73"/>
<Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="#ecf0f3"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="CommandsTemplate">
<RadioButton
GroupName="CommandList"
IsChecked="True"
Content="test"
IsEnabled="false"
Style="{StaticResource CommandButtonStyle}">
</RadioButton>
</DataTemplate>
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding Employee}" ItemTemplate="{StaticResource CommandsTemplate}"/>
</Grid>
I had to throw the inner ItemsControl away since my ViewModel doesn't support tree alike data structure. The person class has no futher lists inside.
However it works all fine.
Take a look at the picture.
Could you please provide us with full code so we have also the same ViewModel as you.
Futhermore remember for any futher questions always give the complete code to us.
Upload it on github.com or anywhere else.
Related
I have a custom contextmenu:
<Window.Resources>
<ContextMenu x:Key="RowMenu" DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}">
<ContextMenu.Style>
<Style TargetType="ContextMenu">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Background="Transparent">
<Border Background="#1c1c1c" Height="70" Width="170" CornerRadius="10">
<StackPanel Orientation="Vertical">
<Button x:Name="openinBrowser" Click="Button_Click_1">
<Grid Width="170">
<materialDesign:PackIcon Kind="OpenInApp" VerticalAlignment="Center" Foreground="{StaticResource PrimaryHueMidBrush}" HorizontalAlignment="Left"/>
<Label FontFamily="Champagne & Limousines" Content="Action 1" FontSize="7" HorizontalAlignment="Center" Foreground="LightGray" VerticalAlignment="Center"/>
</Grid>
<Button.Style>
<Style BasedOn="{StaticResource MaterialDesignRaisedAccentButton}" TargetType="Button">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="{StaticResource PrimaryHueMidBrush}"/>
<Setter Property="BorderThickness" Value="0"/>
</Style>
</Button.Style>
</Button>
</StackPanel>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ContextMenu.Style>
</ContextMenu>
</Window.Resources>
How would I be able to add a name to the Button so I can enable and disable it in my c# (without using binding), I have tried putting x:Name="" but it doesn't work, but if I add a button click it works? I am quite confused, any help would be appreciated!
I still say you should be doing this properly with data-binding, but if you insist...there are a couple of different ways to go about this.
Context menus aren't part of the regular visual tree, so you have to access them directly. Give your context menu a name, and then find the button by traversing its template's visual tree:
// button has to be templated in order for this to work,
// so don't try it in the parent window's constructor
// (add a this.contextMenu.Loaded handler instead if you have to)
var button = this.contextMenu.Template.FindName("openinBrowser", this.contextMenu) as Button;
If your visual tree is particularly complex then a faster option would be to create a boolean resource in your window's resources block:
xmlns:sys="clr-namespace:System;assembly=mscorlib"
<Window.Resources>
<sys:Boolean x:Key="ButtonEnabled">True</sys:Boolean>
</Window.Resources>
...and then bind your button to that dynamically:
<Button x:Name="openinBrowser" IsEnabled="{DynamicResource ButtonEnabled}">
This breaks your "no binding" rule though, which is why I was asking why you're so adamant about not using data-binding...you can still use it, even if you're not binding to the data context. In this scenario you set the value of that resource in your code instead:
this.Resources["ButtonEnabled"] = false;
I want to add conditionnal formatting (just font color) to the textbox part of a combobox. According to MSDN, it's the "PART_EditableTextBox" element. A quick search on SO got me started but I now face a problem: it overrides the whole template. According to this SO answer, I can use "BasedOn" to override only specific properties but I've no idea how/where to use it.
This is my current template:
<ControlTemplate x:Key="MyComboBoxTextBox" TargetType="ComboBox" <!--Here?--> >
<TextBox x:Name="PART_EditableTextBox" <!--Maybe Here?-->>
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="Text" Value="MAL">
<Setter Property="Foreground" Value="DarkOrange"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
</ControlTemplate>
It works, I can still type in valid values and "MAL" does make the text orange but there's no dropdown anymore.
On MSDN, I found the following:
<TextBox x:Name="PART_EditableTextBox"
Style="{x:Null}"
Template="{StaticResource ComboBoxTextBox}"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Margin="3,3,23,3"
Focusable="True"
Background="Transparent"
Visibility="Hidden"
IsReadOnly="{TemplateBinding IsReadOnly}" />
I suppose I should base my template on this "ComboBoxTextBox" but I don't know how to reference it. Do I really need to copy the whole template or is there a way to override a specific property?
EDIT:
On the same MSDN page comboboxTextBox is defined as
<ControlTemplate x:Key="ComboBoxTextBox"
TargetType="{x:Type TextBox}">
<Border x:Name="PART_ContentHost"
Focusable="False"
Background="{TemplateBinding Background}" />
</ControlTemplate>
I don't see how overriding this template removes the dropdown list.
Ok I think I got really confused after reading all of your code and having a really looooooong day at work, I totally missed the point of your question.... which is
I want to add conditionnal formatting (just font color) to the textbox part of a combobox
Well if that's all you want to do, then it's really easy with just a simple style trigger.
I can achieve that with this xaml.
<ComboBox HorizontalAlignment="Center" VerticalAlignment="Center">
<ComboBox.Resources>
<Style TargetType="ComboBox">
<Style.Triggers>
<Trigger Property="Text" Value="MAL">
<Setter Property="Foreground" Value="DarkOrange" />
</Trigger>
</Style.Triggers>
</Style>
</ComboBox.Resources>
<ComboBoxItem>MAL</ComboBoxItem>
<ComboBoxItem>1</ComboBoxItem>
<ComboBoxItem>2</ComboBoxItem>
<ComboBoxItem>3</ComboBoxItem>
</ComboBox>
Hope this helps!
Hello
First sorry for my english.
I have started recently my first project on wpf. I´m styling a custom DataGrid who have been defined programatically (the xaml code doesn´t exists).
I have styled all that i need in my datagrid control except a checkbox that i wrapped inside.
The problem is that in other place of my application i defined a checkbox style how are applying correctly but i can´t apply inside my datagrid.
Actually my datagrid doesn´t throw syntax errors but when the datagrid runs the checkbox styles doesn´t apply.
The style code look like this (its defined in a stylesheet)
... <Setter Property="DataGridCheckBoxColumn.ElementStyle">
<Setter.Value>
<Style TargetType="{x:Type CheckBox}">
<Setter Property="Background" Value="Yellow"/>
<Setter Property="BorderBrush" Value="{DynamicResource NormalBorderBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<BulletDecorator Background="Transparent">
<BulletDecorator.Bullet>
<Grid Width="13" Height="13">
<Border x:Name="Border" Background="Pink" BorderBrush="Black" BorderThickness="1,1,1,1" CornerRadius="2,2,2,2"/>
<Path x:Name="CheckMark" Stroke="Green" StrokeThickness="2" SnapsToDevicePixels="False" Data="M1.5000001,1.5833334 L9.7920001,9.6666667 M1.5420001,9.6666667 L9.7083333,1.5000001" Margin="1" ClipToBounds="False" StrokeEndLineCap="Round" StrokeStartLineCap="Round"/>
</Grid>
</BulletDecorator.Bullet>
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True"/>
</BulletDecorator>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>...
Its exactly the same that it`s applying in the apliccation.
I´ve read a lot about it but i can´t to apply it, i tried, also, setting the setter property to "DatagridBoundColum.ElementStyle" and also to "CellStyle" but it doesn´t work.
Any suggest??
Thank a lot.
Do it like you would do in xaml:
<UserControl.Resources>
<DataTemplate x:Key="CheckBoxTemplate">
<CheckBox Style="{StaticResource AnyResourceKeyInApplciation}"/>
</DataTemplate>
</UserControl.Resources>
<DataGrid x:Name="dataGrid" />
this.dataGrid.Columns.Add(new DataGridTemplateColumn
{
CellTemplate = this.Resources["CheckBoxTemplate"] as DataTemplate
}
);
Thanks for your Reply vorrtex.
I didn´t apply it exactly but it helped me to find the solution, however i would have liked not to modify the VB code and only to modify it the xaml style tag.
I find an object how simplify this task. The syntax it´s the following:
column2.ElementStyle = Application.Current.FindResource("CheckBoxStyle")
It´s applying style ok inside the datagrid. But actually it´s placing at left border of the cell. I´ll try to find why.
Thanks again.
You can try this
<Controls:DataGridCheckBoxColumn Header="Homme" Binding="{Binding Homme}">
<Controls:DataGridCheckBoxColumn.ElementStyle>
<Style TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
<Setter Property="Margin" Value="4,0,0,0"/>
</Style>
</Controls:DataGridCheckBoxColumn.ElementStyle>
</Controls:DataGridCheckBoxColumn>
In my XAML I want to dynamically generate a ListBox with the following:
<ListBox Name="MainListBox">
<Border Style="{DynamicResource ListBoxItemRoundedBorder}">
<ListBoxItem >
<TextBlock>
Some Text Here
</TextBlock>
</ListBoxItem>
</Border>
<Border Style="{DynamicResource ListBoxItemRoundedBorder}">
<ListBoxItem >
<TextBlock>
Some Text Here
</TextBlock>
</ListBoxItem>
</Border>
<Border Style="{DynamicResource ListBoxItemRoundedBorder}">
<ListBoxItem >
<TextBlock>
Some Text Here
</TextBlock>
</ListBoxItem>
</Border>
</ListBox>
I want to add items to this listbox via code behind. How can I add the item and the border via code behind. I can add the list box items easy enough but can't seem to figure out the border:
For Each s As String in MyArray
Dim lbi as New ListBoxItem()
Dim tb as New TextBlock()
tb.Text = s
lbi.content = tb
MainListBox.Items.Add(lbi)
Next
Edit: To clear up any confusion I want a border around each of the ListBox Items. I've updated the XAML - effectively I want to render that XAML dynamically, or equivalent, via code behind. I already have the border style defined.
Have you looked in to Templating the ListBoxItem
Use this to get the border effect you're looking for
<Style x:Key="ListBoxItemRoundedBorder" TargetType="ListBoxItem">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border
Name="Border"
Padding="2"
SnapsToDevicePixels="true" Style="{DynamicResource RoundedBorder}">
<ContentPresenter />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="Border" Property="Background"
Value="{StaticResource SelectedBackgroundBrush}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground"
Value="{StaticResource DisabledForegroundBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then on your listbox use
<ListView ItemContainerStyle="{StaticResource ListBoxItemRoundedBorder}" />
Although, based on your question, I can't exactly see what design your looking for. Are you looking for a List with a border around it or a list with a border around each item?
I don't understand. If you want one Border, why not just stick it on the outside of the ListBox? I'll assume you want one Border per ListBoxItem. In that case, just modify the ItemTemplate:
<ListBox>
<ListBox.ItemTemplate>
<Border>
<TextBlock Text="{Binding}"/>
</Border>
</ListBox.ItemTemplate>
</ListBox>
"I want to add items to this listbox via code behind."
I have just built a page that loads controls to the page dynamically (based on a collection).
So to answer the the question... you must apply the settings (like what is done with the templating in xaml) in your code. Here is an example in C#: (in vb the first line would start with Dim listBoxStyle as Style...)
Style listBoxStyle = new System.Windows.Style(typeof(ListBox));
listBoxStyle.Setters.Add(new Setter(ListBox.BorderThicknessProperty, new Thickness(0,0,0,0)));
ListBox rdoList = new ListBox();
rdoList.Resources.Add(typeof(ListBox), listBoxStyle);
Notice the thickness(). I have mine set to no border as it defaults to having a border. You can do this with your textboxes and just add the thickness like (1,1,1,1).
Don't know how your calling your dynamic controls from code but you may want to view this post for an easy way to access dynamic wpf controls by name value from code.
Been banging my head against this all morning.
Basically, I have a listbox, and I want to keep people from changing the selection during a long running process, but allow them to still scroll.
Solution:
All the answers were good, I went with swallowing mouse events since that was the most straight forward. I wired PreviewMouseDown and PreviewMouseUp to a single event, which checked my backgroundWorker.IsBusy, and if it was set the IsHandled property on the event args to true.
If you look in to the control template of the ListBox, there is a ScrollBar and ItemsPresenter inside. So Make the ItemsPresenter Disabled and you will get this easily. Use the bellow Style on the ListBox and you are good to go.
<Style x:Key="disabledListBoxWithScroll" TargetType="{x:Type ListBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<Border x:Name="Bd" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="1">
<ScrollViewer Padding="{TemplateBinding Padding}" Focusable="false">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" IsEnabled="False" IsHitTestVisible="True"/>
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
</Trigger>
<Trigger Property="IsGrouping" Value="true">
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
On the ListBox use the Style
<ListBox Style="{DynamicResource disabledListBoxWithScroll}" ..... />
I found that putting a disabled ListBox in a ScrollViewer with auto scrolling enabled gives the desired effect.
The trick is to not really disable. Disabling will lock out all messages from the scroll box.
During the long operation, gray out the text in the list box using its .ForeColor property and swallow all mouse clicks. This will simulate disabling the control and allow scrolling unimpeded.
While it's for Silverlight, maybe this blog post would help you get going in the right direction? Silverlight No Selection ListBox and ViewBox
I used this solution, it's really easy and works perfectly:
For every SurfaceListBoxItem item you put in the Listbox, do this:
item.IsHitTestVisible = false;
This worked best for me. It's easy and whole code is in XAML which is IMO very neat.
<ListBox ItemsSource="{Binding MySource}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding IsEditing}" Value="True">
<Setter Property="IsEnabled" Value="True"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsEditing}" Value="False">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Another option worth considering is disabling the ListBoxItems. This can be done by setting the ItemContainerStyle as shown in the following snippet.
<ListBox ItemsSource="{Binding YourCollection}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsEnabled" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
If you don't want the text to be grey you can specify the disabled color by adding a brush to the style's resources with the following key: {x:Static SystemColors.GrayTextBrushKey}. The other solution would be to override the ListBoxItem control template.
This question is pretty much the same as this one: There ain't ListBox.SelectionMode=“None”, is there another way to disable selection in a listbox? and my answer is the same.
I found a very simple and straight forward solution working for me, I hope it would do for you as well
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Focusable" Value="False"/>
</Style>
A complete answer using http://www.codeproject.com/Tips/60619/Scrollable-Disabled-ListBox-in-WPF
The Style:
<Style TargetType="{x:Type local:CustomListBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:CustomListBox}">
<Border SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="1">
<ScrollViewer IsEnabled="True">
<ItemsPresenter IsEnabled="{Binding Path=IsEnabledWithScroll, RelativeSource={RelativeSource TemplatedParent}}" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"/>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The class
public class CustomListBox : ListBox
{
public bool IsEnabledWithScroll
{
get { return (bool)GetValue(IsEnabledWithScrollProperty); }
set { SetValue(IsEnabledWithScrollProperty, value); }
}
public static readonly DependencyProperty IsEnabledWithScrollProperty =
DependencyProperty.Register("IsEnabledWithScroll", typeof(bool), typeof(CustomListBox), new UIPropertyMetadata(true));
}
Then instead of setted IsEnabled on the ListBox, use IsEnabledWithScroll instead. Scrolling will work if the listbox is enabled or disabled.
There seem to be many ways to skin this particular cat. I found that by setting IsHitTestVisible on the ItemsContainerStyle in XAML I got exactly what I needed:
<ListBox IsHitTestVisible="true" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.CanContentScroll="True">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsHitTestVisible" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Well, I found a sweet way to provide this feature. What I did is that in the DataTemplate of the listBox I binded the parent layout enable property with the boolean flag using Page as Source.
Step 1 - Provide the x:Name attribute to the page. If the page you are using is extended with base page than make sure that the base page is not an abstract class and has an default constructor without any arguments.
<Page x:Class="OPMS.Views.Registration"
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"
x:Name="MainPage"
d:DesignWidth="1024"
Title="Registration"
>
Step 2 - Use the Page as a source for the DataTemplate parent layout items IsEnabled property
<ListBox Grid.Row="2"
ItemsSource="{Binding TestGroups}"
AlternationCount="2"
Padding="0"
Margin="10,5,10,10"
>
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}"
IsChecked="{Binding IsSelected}"
IsEnabled="{Binding Source={x:Reference MainPage}, Path=DataContext.BindingVariableHere}"
/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>