Windows Phone - DependencyProperties - silverlight

I'm trying to get a UserControl working in Windows Phone 7. I have a few properties which I'd like to bind to, yet they aren't populated regardless of whether I add them as DependencyProperties or not. The only way I can get them to work is by setting the DataContext instead. The code I've tried is (for one property):
public static readonly DependencyProperty MaximumItemsProperty = DependencyProperty.Register("MaximumItems", typeof(int), typeof(ManageIngredientsControl), new PropertyMetadata(0));
/// <summary>
/// Gets or sets the maximum number of items to match.
/// </summary>
/// <value>The maximum number of items to match.</value>
public int MaximumItems
{
get { return Convert.ToInt32(base.GetValue(MaximumItemsProperty)); }
set { base.SetValue(MaximumItemsProperty, value); }
}
<TextBox Grid.Row="1" Grid.Column="1" x:Name="nudMaxIngredients" Width="120" Text="{Binding MaximumItems,Mode=TwoWay,ElementName=root}" InputScope="Number" />
The root UserControl element is called 'root', but the value isn't populated. The only way to get it half working is by using this:
public int MaximumItems
{
get { return Convert.ToInt32(DataContext) }
set { DataContext = value; }
}
It seems something's interfering with the DataContext, but if I'm binding to DependencyProperties why would it matter?

I'm guessing that your TextBox is inside your UserControl. If so, then ElementName binding has an issue, as described here.
Basically, the name you give the UserControl in it's XAML is overwritten by any name given to it where it's used (i.e. in your Page).
The workaround is to use something like:
<TextBox Grid.Row="1" Grid.Column="1" x:Name="nudMaxIngredients" Width="120" Text="{Binding Parent.MaximumItems,Mode=TwoWay,ElementName=LayoutRoot}" InputScope="Number" />
Where LayoutRoot is the root control inside the UserControl's XAML.
Also, your first approach to the MaximumItems property is correct.

Related

Difference Source and Datacontext in wpf

DataContext and Source seem to be very similar to me.
What are the advantages and disadvantages?
When to use which one?
With Source:
<TextBlock Text="{Binding Name, Source={StaticResource Person}}" />
Or the solution with DataContext:
public partial class DataContextSample : Window
{
public string Name {get; set;}
public DataContextSample()
{
InitializeComponent();
this.DataContext = this;
}
}
<TextBlock Text="{Binding Name}" />
A binding with out a specified Source binds to the DataContext property of the element.
The DataContext is a special property which, if not set, is redirected to the element's parent's DataContext. This prevents duplicate xaml (always setting the Source in every binding) and makes all bindings relative so it is easier to change the UI without having to adjust all Sources in the bindings.

Bind user control dependency properties in MVVM style Windows Phone app

I'm having some issues with binding some custom controls in a Windows Phone app right now. Usually this is never an issue but apparently my mind can't comprehend this today.
So I'm doing an MVVM style setup which is good. I have my page with a view and also a viewmodel. Now on a WebClient callback I assign the dataContext of my view to the list of models in my ViewModel, nice and simple thus far...now in my view I created a ListBox with a custom control in the datatemplate which is basically a cell in the list. I once again set my user controls dataContext to binding, and binding all the models values to the regular UI elements works no problem.
Here's a sample:
<Grid Grid.Column="0">
<Image Source="{Binding SmallPath}" VerticalAlignment="Top"/>
</Grid>
<Grid Grid.Column="1">
<StackPanel Margin="12,0,0,0">
<TextBlock x:Name="MemberId_TextBlock" Text="{Binding MemberId}" FontSize="28"
Margin="0,-8,0,0"
Foreground="{StaticResource PhoneForegroundBrush}"/>
<StackPanel Orientation="Horizontal" Margin="0,-11,0,0">
<TextBlock Text="{Binding DaysReported}" FontSize="42"
Margin="0,0,0,0"
Foreground="{StaticResource PhoneAccentBrush}"/>
<TextBlock Text="days" FontSize="24"
Margin="3,19,0,0"
Foreground="{StaticResource PhoneSubtleBrush}"/>
</StackPanel>
</StackPanel>
</Grid>
That's in my user control, and here's the the view where the usercontrol is housed:
<Grid x:Name="LayoutRoot" Background="Transparent">
<ListBox Name="TopSpotter_ListBox" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<!--<TextBlock Text="{Binding MemberId}"/>-->
<controls:TopSpotterItemControl DataContext="{Binding}"/>
<Grid Height="18"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Now this is good enough but what I want to do in my view is set data from my model like Booleans that determine whether or not I should show certain Grids etc. So if I try to set a dependency property explicitly in my control it fires and will run logic in the Getter/Setters for instance. HOWEVER if I try to set these custom objects from a binding source it won't actually set.
Here's what works:
<controls:TopSpotterItemControl ChampVisibility="True">
This way will trigger the ChampVisibility property and then in the code behind of the user control I can set visibilities.
Here's what fails but I want to work:
<controls:TopSpotterItemControl ChampVisibility="{Binding IsChamp">
In addition I can still set the DataContext to {Binding} and the result will be unchanged.
In this scenario IsChamp is part of my model that I would like to bind to this user control which I guess comes from the dataContext being set on the view from the viewModel. I'm not sure what I can do to get this so the bindings work etc. without having to set custom properties.
Finally, here's my user control:
public partial class TopSpotterItemControl : UserControl
{
public string MemberId
{
get
{
return this.MemberId_TextBlock.Text;
}
set
{
this.MemberId_TextBlock.Text = value;
}
}
public bool ChampVisibility {
set
{
if (value)
{
this.Champ_Grid.Visibility = System.Windows.Visibility.Visible;
}
}
}
public static readonly DependencyProperty MemberNameProperty =
DependencyProperty.Register("MemberId", typeof(string), typeof(TopSpotterItemControl), new PropertyMetadata(null));
public static readonly DependencyProperty ChampVisibilityProperty =
DependencyProperty.Register("ChampVisibility", typeof(bool), typeof(TopSpotterItemControl), new PropertyMetadata(null));
public TopSpotterItemControl()
{
InitializeComponent();
}
}
Bit long winded and I hope I made things on the issue clear. My one major hang up so far, and I'd like to abstract as much control as I can to the user control via dependency properties explicitly set in xaml, rather than setting up binding in its xaml that depend on the knowledge of a model. Thanks!
Your DependencyProperty is badly formed. (I also don't see Champ_Grid defined in your class or XAML, but I assume that is an ommission)
Setting ChampVisibility = true in code works because it is unrelated to the DependencyProperty.
You can tell easily because the default value for your DP is invalid. It will compile, but the instance constructor will through an exception if it is ever invoked.
new PropertyMetadata(null)
bool = null = exception
If you call GetValue(TopSpotterItemControl.ChampVisibilityProperty) from somewhere you can confirm all of the above.
You should make changes to instance fields in the property changed handler and declare the property like the following, it will work:
Note that the property has to change (not just be set) for the event to be raised.
public bool ChampVisibility
{
get { return (bool)GetValue(ChampVisibilityProperty); }
set { SetValue(ChampVisibilityProperty, value); }
}
public static readonly DependencyProperty ChampVisibilityProperty =
DependencyProperty.Register("ChampVisibility ", typeof(bool), typeof(TopSpotterItemControl), new PropertyMetadata(true, (s, e) =>
{
TopSpotterItemControl instance = s as TopSpotterItemControl;
instance.Champ_Grid.Visibility = instance.ChampVisibility ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
}));
Incidentally, your MemberId DependencyProperty is also completely wrong and cannot work.
Note:
The Binding on your TextBox works, because it is binding to the DataContext (your model), so it probably shows the right value.
The Dependency property in your UserControl will never be set though.
Use the propdp code-snippet in Visual Studio so you dont have to concern yourself with the complexities of Dependency Property declaration.
Also check this out for more info about Dependency Properties

WPF Binding DataTable Row Column to textbox

NARROWED DOWN SOLUTION
I'm much closer, but don't know how to apply XAML to change datacontext value. Please review context of original question below as may be needed.
My issue is that I have a ViewModel class as the datacontext to a window. On this view model, I have a "DataTable" object (with columns and just a single row for testing). When I try to set a Textbox "TEXT" binding to the column of the datatable, it doesn't work. What I've ultimately found is that no matter what "source" or "path" I give it, it just won't cooperate. HOWEVER, just by playing around with scenarios, I said the heck with it. Lets look. The Textbox control has its own "DataContext" property. So, in code, I just FORCED the textbox.DataContext = "MyViewModel.MyDataTableObject" and left the path to just the column it should represent "MyDataColumn", and it worked.
So, that said, how would I write the XAML for the textbox control so it's "DataContext" property is set to that of the datatable object of the view model the window but can't get that correct. Ex:
<TextBox Name="myTextBox"
Width="120"
DataContext="THIS IS WHAT I NEED" --- to represent
Text="{Binding Path=DataName,
ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged }" />
DataContext for this textbox should reflect XAML details below and get
(ActualWindow) ( DDT = View Model) (oPerson = DataTable that exists ON the view model)
CurrentWindow.DDT.oPerson
I'm stuck on something with binding. I want to bind a column of a datatable to a textbox control. Sounds simple, but I'm missing something. Simple scenario first. If I have my window and set the data context to that of "MyDataTable", and have the textbox PATH=MyDataColumn, all works fine, no problems, including data validation (red border on errors).
Now, the problem. If I this have a same "MyDataTable" as a public on my Window Class directly (but same thing if I had it on an actual ViewModel object, but the window to simplify the level referencing), I can't get it to work from direct XAML source. I knew I had to set the "SOURCE=MyDataTable", but the path of just the column didn't work.
<TextBox Name="myTextBox"
Text="{Binding Source=DDT, Path=Rows[0][DataName],
ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged }" />
However, from other testing, if I set the path (in code-behind) to
object txt = FindName("myTextBox");
Binding oBind = new Binding("DataName");
oBind.Source = DDT;
oBind.Mode = BindingMode.TwoWay;
oBind.ValidatesOnDataErrors = true;
oBind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
((TextBox)txt).SetBinding(TextBox.TextProperty, oBind);
It DOES work (when the datatable is available as public in the window (or view model))
What am I missing otherwise.
UPDATE: HERE IS A FULL POST of the sample code I'm applying here.
using System.ComponentModel;
using System.Data;
namespace WPFSample1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public DerivedDataTable DDT;
public MainWindow()
{
InitializeComponent();
// hook up to a Data Table
DDT = new DerivedDataTable();
DataContext = this;
// with THIS part enabled, the binding works.
// DISABLE this IF test, and binding does NOT.
// but also note, I tried these same settings manually via XAML.
object txt = FindName("myTextBox");
if( txt is TextBox)
{
Binding oBind = new Binding("DataName");
oBind.Source = DDT;
oBind.Mode = BindingMode.TwoWay;
oBind.ValidatesOnDataErrors = true;
oBind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
((TextBox)txt).SetBinding(TextBox.TextProperty, oBind);
}
}
}
// Generic class with hooks to enable error trapping at the data table
// level via ColumnChanged event vs IDataErrorInfo of individual properties
public class MyDataTable : DataTable
{
public MyDataTable()
{
// hook to column changing
ColumnChanged += MyDataColumnChanged;
}
protected void MyDataColumnChanged(object sender, DataColumnChangeEventArgs e)
{ ValidationTest( e.Row, e.Column.ColumnName); }
// For any derived datatable to just need to define the validation method
protected virtual string ValidationTest(DataRow oDR, string ColumnName)
{ return ""; }
}
public class DerivedDataTable : MyDataTable
{
public DerivedDataTable()
{
// simple data table, one column, one row and defaulting the value to "X"
// so when the window starts, I KNOW its properly bound when the form shows
// "X" initial value when form starts
Columns.Add( new DataColumn("DataName", typeof(System.String)) );
Columns["DataName"].DefaultValue = "X";
// Add a new row to the table
Rows.Add(NewRow());
}
protected override string ValidationTest(DataRow oDR, string ColumnName)
{
string error = "";
switch (ColumnName.ToLower())
{
case "dataname" :
if ( string.IsNullOrEmpty(oDR[ColumnName].ToString() )
|| oDR[ColumnName].ToString().Length < 4 )
error = "Name Minimum 4 characters";
break;
}
// the datarow "SetColumnError" is what hooks the "HasErrors" validation
// in similar fashion as IDataErrorInfo.
oDR.SetColumnError(Columns[ColumnName], error);
return error;
}
}
}
AND here's the XAML. Any brand new form and this is the only control in the default "grid" of the window.
Tried following versions, just defining the Rows[0][Column]
<TextBox Name="myTextBox"
Width="120"
Text="{Binding Path=Rows[0][DataName],
ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged }" />
Including the source of "DDT" since it is public to the window
<TextBox Name="myTextBox"
Width="120"
Text="{Binding Source=DDT, Path=Rows[0][DataName],
ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged }" />
And even suggestions offered by grantnz
I think your xaml is setting the source to the string "DDT" when you're expecting it to be the property DDT on the current window.
Do you see an error in the output window of Visual Studio like:
System.Windows.Data Error: 40 : BindingExpression path error:
'Rows' property not found on 'object' ''String' (HashCode=1130459074)'.
BindingExpression:Path=Rows[0][DataName]; DataItem='String' (HashCode=1130459074);
target element is 'TextBox' (Name=''); target property is 'Text' (type 'String')
If you set the window DataContext to this (from code DataContext = this; or xaml), you can use:
Text="{Binding Path=DDT.Rows[0][DataName],
ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged }" />
or you can leave the DataContext as null and use:
<TextBox Name="myTextBox"
Text="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Window}},Path=DDT.Rows[0][DataName],
ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged }" />
The above assumes that you are setting the DDT property before the binding is set-up. If DDT is set after the binding is configured, you'll need to implement INotifyPropertyChanged.
Here's the source of a working version (with DataContext set from XAML and INotifyPropertyChanged implemented). It doesn't work if you comment out the line
OnPropertyChanged(new PropertyChangedEventArgs("DDT"));
and the second TextBox is bound if you leave out the following out of the XAML
DataContext="{Binding RelativeSource={RelativeSource Self}}"
CODE
public partial class MainWindow : Window, INotifyPropertyChanged
{
public DataTable DDT { get; set; }
public String SP { get; set; }
public MainWindow()
{
InitializeComponent();
DDT = new DerivedDataTable();
OnPropertyChanged(new PropertyChangedEventArgs("DDT"));
SP = "String prop";
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged(this, e);
}
}
XAML
<Window x:Class="BindingTest.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"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<StackPanel>
<TextBox
Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}},Path=DDT.Rows[0][DataName],
ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged }" />
<TextBox
Text="{Binding Path=DDT.Rows[0][DataName],
ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged }" />
<TextBox
Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}},Path=SP}" />
</StackPanel>
</Window>
SOLVED, but what a PITA... Most things within the samples of doing MVVM patterns will have properties on the view model exposing whatever you want to hook into. When dealing with binding to a DATATABLE (or similar view, etc), you are binding to COLUMNs of said table (or view).
When a table is queried from whatever back-end, the schema populating the data columns will always force the column names to UPPER CASE.
So, if you have a column "InvoiceTotal" in your table, when queried, the column name will have it as "INVOICETOTAL".
If you try to bind to the
Path="InvoiceTotal" ... it will fail
Path="INVOICETOTAL" ... it WILL WORK
However, if you are working directly in .Net (I use C#), the following will BOTH get a value back from the row
double SomeValue = (double)MyTable.Rows[0]["InvoiceTotal"];
or
double SomeValue = (double)MyTable.Rows[0]["INVOICETotal"];
or
double SomeValue = (double)MyTable.Rows[0]["invoicetotal"];
all regardless of the case-sensitivity of the column name.
So, now the rest of the bindings, Error triggers available at the table, row or column levels can properly be reflected in the GUI to the user.
I SURE HOPE this saves someone else the headaches and research I have gone through on this....

Access the child control of a user control

I have created a user control that consists of a expander, listbox and checkboxes. I am not able to access the checkboxes (child control) and I want to generate the number of expanders based on the number of rows in a table dynamically. Can anyone suggest the possible solutions to
This is extremely vague. In most cases you would just expose some of the internal control's properties, e.g. if you want to create dynamic content you would expose the ItemsSource and ItemTemplate of an internal ListBox of whatever you use so it can be set from outside, e.g.
<UserControl x:Class="Test.UserControls.Bogus" 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" Name="control">
<StackPanel>
<TextBlock Text="Lorem Ipsum:" />
<ItemsControl ItemsSource="{Binding ElementName=control, Path=ItemsSource}"
ItemTemplate="{Binding ElementName=control, Path=ItemTemplate}" />
</StackPanel>
</UserControl>
public partial class Bogus : UserControl
{
public static readonly DependencyProperty ItemsSourceProperty = ItemsControl.ItemsSourceProperty.AddOwner(typeof(Bogus));
public IEnumerable ItemsSource
{
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
public static readonly DependencyProperty ItemTemplateProperty = ItemsControl.ItemTemplateProperty.AddOwner(typeof(Bogus));
public DataTemplate ItemTemplate
{
get { return (DataTemplate)GetValue(ItemTemplateProperty); }
set { SetValue(ItemTemplateProperty, value); }
}
public Bogus()
{
InitializeComponent();
}
}
Usage:
<uc:Bogus ItemsSource="{Binding Data}">
<uc:Bogus.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" Foreground="Red" />
</DataTemplate>
</uc:Bogus.ItemTemplate>
</uc:Bogus>
You can of course also encapsulate a lot of logic which you do not need exposed.
Since you want a varying amount of expanders you might have an ItemsControl (unlike a ListBox it has no selection) which already defines an ItemTemplate which contains an expander. You probably can also create a partial template as shown in this answer of mine.
Sounds like you need to navigate the visual tree. The simplest way of doing this is via Linq-to-VisualTree. To find all the CheckBoxes that are a child of 'this', use the following query:
IEnumerable<CheckBox> checks = this.Descendants<CheckBox>().Cast<CheckBox>();
Your application is running in an Application instance. Access the usercontrol components with Application.usercontrol.ComponentName if it is not a UI update. If you make UI updates, you have to run the access in a separate dispatcher thread. In that case, use BackgroundWorker.
For example, I am running my main application class MainWindow and accessing it as,
MainWindow rootWindow = Application.Current.MainWindow as MainWindow;
Now access the usercontrol and properties of components as:
rootWindow.usercontrolX.ComponentY.PropertyZ
Define properties in the child's class for each of those controls. You will be able to access them from the Parent User Control, assuming you have added the Child User Control within the Parent User Control.
Parent User Control.. SingalData is the child User Contol
<my:C1TabItem Header="Signal">
<local:SignalData Width="1036" OnSignalNameChange="SignalInputTab_OnSignalNameChange" Loaded="SignalInputTab_Loaded" Height="353" VerticalAlignment="Top" MinHeight="353" HorizontalAlignment="Left"></local:SignalData>
In the Child User Contorl class, if you have a component named tabProductList you add a property -
public C1.WPF.C1TabControl TabProductList
{
get { return this.tabProductList; }
}
And finally, from your parent class you can reference it as -
C1TabItem tbItem = (C1TabItem)c1TabControl1.SelectedItem;
SignalData sigInp = (SignalData)tbItem.Content;
if (sigInp.TabProductList.SelectedIndex == 0)
{
....

WPF Databinding CheckBox.IsChecked

How would I bind the IsChecked member of a CheckBox to a member variable in my form?
(I realize I can access it directly, but I am trying to learn about databinding and WPF)
Below is my failed attempt to get this working.
XAML:
<Window x:Class="MyProject.Form1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Title" Height="386" Width="563" WindowStyle="SingleBorderWindow">
<Grid>
<CheckBox Name="checkBoxShowPending"
TabIndex="2" Margin="0,12,30,0"
Checked="checkBoxShowPending_CheckedChanged"
Height="17" Width="92"
VerticalAlignment="Top" HorizontalAlignment="Right"
Content="Show Pending" IsChecked="{Binding ShowPending}">
</CheckBox>
</Grid>
</Window>
Code:
namespace MyProject
{
public partial class Form1 : Window
{
private ListViewColumnSorter lvwColumnSorter;
public bool? ShowPending
{
get { return this.showPending; }
set { this.showPending = value; }
}
private bool showPending = false;
private void checkBoxShowPending_CheckedChanged(object sender, EventArgs e)
{
//checking showPending.Value here. It's always false
}
}
}
<Window ... Name="MyWindow">
<Grid>
<CheckBox ... IsChecked="{Binding ElementName=MyWindow, Path=ShowPending}"/>
</Grid>
</Window>
Note i added a name to <Window>, and changed the binding in your CheckBox. You will need to implement ShowPending as a DependencyProperty as well if you want it to be able to update when changed.
Addendum to #Will's answer: this is what your DependencyProperty might look like (created using Dr. WPF's snippets):
#region ShowPending
/// <summary>
/// ShowPending Dependency Property
/// </summary>
public static readonly DependencyProperty ShowPendingProperty =
DependencyProperty.Register("ShowPending", typeof(bool), typeof(MainViewModel),
new FrameworkPropertyMetadata((bool)false));
/// <summary>
/// Gets or sets the ShowPending property. This dependency property
/// indicates ....
/// </summary>
public bool ShowPending
{
get { return (bool)GetValue(ShowPendingProperty); }
set { SetValue(ShowPendingProperty, value); }
}
#endregion
You must make your binding mode as TwoWay :
<Checkbox IsChecked="{Binding Path=ShowPending, Mode=TwoWay}"/>
If you have only one control that you want to bind to a property of your code-behind, then you can specify this as the source in your binding via a RelativeSource like this:
<CheckBox ...
IsChecked="{Binding ShowPending, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}">
That could be the end of the answer. But more generally you will have multiple controls and wish to bind them to various properties on your class. In this case it is neater and more convenient to make use of the fact that the DataContext property (which is the default source object for data binding) is inherited down through the control hierarchy, so setting it at the top level will make it available to all the child controls.
There is no default value for DataContext, but there are at least two ways you can set the DataContext property of your Window element to point at itself:
By setting DataContext = this in the code-behind constructor. This is very simple, but some might argue that it's not clear in the XAML where the DataContext is pointing.
By setting the DataContext in XAML using DataBinding
The simplest and, I think, most elegant way to set the DataContext at the Window/UserControl level in XAML is very straight forward; just add DataContext="{Binding RelativeSource={RelativeSource Self}}" to your Window element. RelativeSource Self just means "bind directly to the object", which in this case is the Window object. The lack of a Path property results in the default Path, which is the source object itself (i.e. the Window).
<Window x:Class="MyProject.Form1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<CheckBox ...
IsChecked="{Binding ShowPending}">
</CheckBox>
</Grid>
</Window>
Once you have done this, the DataContext property for all child controls will be the Window class, so data binding to properties in your code-behind will be natural.
If for some reason you don't want to set the DataContext on the Window, but wish to set it lower down the control hierarchy, then you can do so by using the FindAncestor mechanism. E.g. if you want to set it on the Grid element and all children of the Grid:
<Grid DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}">
<CheckBox ...
IsChecked="{Binding ShowPending}">
</CheckBox>
</Grid>
It's probably worth noting at this point that what we have achieved so far is the ability to bind a UI Control to a property of your code-behind class, and for that code-behind property to be kept up-to-date with changes to the UI element. So if the user checks the CheckBox, the ShowPending property will be updated.
But quite often you also want the reverse to be true; a change to the source property should be reflected in a corresponding change to the UI Control. You can see this by adding another CheckBox control to your window, bound to the same ShowPending property. When you click one checkbox, you would probably hope or expect the other Checkbox to be synchronized, but it won't happen. To achieve this your code-behind class should either (a) implement INotifyPropertyChanged, (b) add a ShowPendingChanged event or (c) make ShowPending a Dependency Property. Of the 3, I suggest implementing INotifyPropertryChanged on your code-behind is the most common mechanism.

Resources