same two user control in xaml - wpf

I have one user control in wpf. And I want to use this user control two times in same view.
I am using mvvm approach. Can anybody give me a good suggestion that what approach I should follow.

Um, any reason why you aren't just using it twice? If you bind to the VM (as the DataContext) with the same properties, it will "just work," no differently than binding two TextBlocks (or other "regular" control) to the same property in the VM.
Here I use the same control in the same window, but it could just as easily be used in the same UserControl, DataTemplate, etc. - whatever you are defining as a "view".
XAML
<Window x:Class="MyNamespace.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyNamespace"
Title="My Window" Width="300" Height="300">
<StackPanel>
<local:MyUserControl x:Name="control1"
SomeProperty="{Binding MyMVVMProperty}" />
<local:MyUserControl x:Name="control2"
SomeProperty="{Binding MyMVVMProperty}" />
<TextBlock x:Name="txt1"
Text="{Binding AnotherMVVMProperty}" />
<TextBlock x:Name="txt2"
Text="{Binding AnotherMVVMProperty}" />
<TextBlock x:Name="txt3"
Text="{Binding AThirdMVVMProperty}" />
</StackPanel>
</Window>
Code Behind
class Window1 : Window
{
MyViewModel mViewModel = new MyViewModel();
public Window1()
{
this.DataContext = mViewModel;
}
}

Related

Modify content of resource

I have a UserControl that contains a TabControl that has an ItemTemplate that in turn has a Button. I want the user be able to change the content of that button, e.g. change it from TextBlock to Image.
A solution I thought of was to set the button's content from the Resources of the UserControl and overwrite the Resource by setting it on the ResourceDictionary of the entailing Window. Of course that does not work as StaticResource always resolves to the "closest" instance it can find.
I then thought of modifying the resource in the constructor of my UserControl, depending on some property. But it seems, one cannot change a resource. Below is a close sample showing the idea with a simple ListBox in a Window in which I try to change "What" to "How".
How would you approach this?
<Window.Resources>
<TextBlock x:Key="key" Text="What: " x:Shared="false" />
</Window.Resources>
<Grid Margin="10">
<ListBox Name="lbTodoList" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<StaticResource ResourceKey="key" />
<TextBlock Text="{Binding}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
TextBlock tb = FindResource("key") as TextBlock;
tb.Text = "How: ";
List<string> items = new List<string>();
items.Add("Item 1");
items.Add("Item 2");
items.Add("Item 3");
lbTodoList.ItemsSource = items;
}
}
Instead of trying to override a resource, you should just treat it like any other XAML data-binding templating issue.
Instead of:
<StaticResource ResourceKye="key" />
Do something like this:
<TextBlock Text="{Binding LabelText}" />
In your UserControl set the default value of LabelText to "What:" and then allow the user to override the value. The data binding will take care of the rest.
If you want to have more dynamic content, then use a ContentControl instead and have properties for Content, ContentTemplate, and even ContentTemplateSelector depending on what you need to do.
<ContentControl
Content="{Binding MyContent}"
ContentTemplate="{Binding MyContentTemplate}"
ContentTemplateSelector="{Binding MyContentTemplateSelector}" />
This opens up a lot of flexibility.

Assign different ViewModels to one UserControl

I have MainWindow.xaml page with it's MainViewModel
and would like to add 2 SidePanels using one UserControl, but it should have different ViewModels.
MainViewModel alredy has 2 properties with created SidePanelViewModels:
public MainViewModel()
{
LeftSidePanel = new SidePanelViewModel(PanelSides.Left);
RightSidePanel = new SidePanelViewModel(PanelSides.Right);
}
How to set objects in this properties as DataContext for each UserControl in xaml?
Something like this doesnot work:
<Window DataContext="{Binding MainViewModel, Source={StaticResource Locator}}">
...
<Grid Visibility="{Binding RightSidePanel.PanelVisibility}" Grid.Column="4" Grid.Row="2" >
<v:SidePanelViev DataContext="{Binding RightSidePanel}" />
</Grid>
</Window>
I broke all the brains thinking how to do it, Please help
ps.
Or please suggest any other approach to reach the same target..
I have solved my problem by adding both instances of SidePanelViewModel as Content of ContentControl
<Window DataContext="{Binding MainViewModel, Source={StaticResource Locator}}">
...
<Grid Visibility="{Binding RightSidePanel.PanelVisibility}" Grid.Column="4" Grid.Row="2" >
<ContentControl Content="{Binding RightSidePanel}"></ContentControl>
</Grid>
</Window>
and adding new Window.Resource what binds all classes of type SidePanelViewModel to be visualised using SidePanelViev
<Window.Resources>
<DataTemplate DataType="{x:Type vm:SidePanelViewModel}">
<v:SidePanelViev></v:SidePanelViev>
</DataTemplate>
</Window.Resources>
This works, but if somebody has better ideas, please do not hesitate to post them, I am not sure that my decision is good one

WPF: Set UserControl DataContext

I have the following MainWindow that lays out a left side navigation panel and a right side display area (both of these are UserControls).
Can someone explain how to assign the DataContext of the navigation panel (LinksView.xaml) to that of LinksViewModel.cs. I would like to bind a Command (BtnCompanyClickCommand) to the button and define BtnCompanyClickCommand in LinksViewModel.cs.
I have tried various methods that I found on StackOVerflow to set the DataContext but none of these solutions seem to work (binding RelativeSource, naming view and binding to name, etc.).
MainWindow.xaml
<StackPanel Orientation="Horizontal">
<vw:LinksView DataContext="{Binding RelativeSource={RelativeSource Self}}"/>
<ContentControl Content="{Binding CurrentUserControl}" />
</StackPanel>
LinksView.xaml
<StackPanel Orientation="Vertical">
<Button Content="Company" Width="75" Margin="3" Command="{Binding ElementName=Links,Path=BtnCompanyClickCommand}" />
</StackPanel>
FormsDictionary.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:SidekickAdmin.ViewModel"
xmlns:vw="clr-namespace:SidekickAdmin.View">
<DataTemplate DataType="{x:Type vm:CompanySummaryViewModel}">
<vw:CompanySummaryView>
<ContentControl Content="{Binding }" />
</vw:CompanySummaryView>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:LinksViewModel}">
<vw:LinksView />
</DataTemplate>
</ResourceDictionary>
EDIT
So I finally came across this explanation of how to set the DataContext of a UserControl which has to be done on the first child item of the UserControl.
Here is the modified LinksView.xaml that works.
<StackPanel Orientation="Vertical">
<StackPanel.DataContext>
<vm:LinksViewModel /> <!-- Bind the items in StackPanel to LinksViewModel -->
</StackPanel.DataContext>
<Button Content="Company" Width="75" Margin="3" Command="{Binding BtnCompanyClickCommand}" />
</StackPanel>
However, I am still not clear on why I have to set the DataContext of the child element and not the UserControl and why the DataTemplate for LinksView (set in FormsDictionary.xaml) doesn't tie into the DataContext of LinksViewModel. Any explanation would be appreciated.
First you have to refer to your DataContext (LinksViewModel.cs) in your XAML code.
You can do that either by directly instantiating it or use a ResourceDictionary. In the latter case you instantiate your DataConext either inside some .cs file or inside the ResourceDictionary .xaml file and store it in a named ResourceDictionary where you can find the reference later.
Second you simply have to associate the DataContext property of a View element like your LinksView.xaml with the corresponding DataContext.
This is pretty high-level and without any code but that's the basic idea behind it.
there should be an instance of LinksViewModel in MainWindowViewModel:
MainWindowViewModel.cs:
class MainWindowViewModel
{
public MainWindowViewModel()
{
LinksVM = new LinksViewModel();
}
public LinksViewModel LinksVM { get; private set; }
}
MainWindow.xaml
<StackPanel Orientation="Horizontal">
<vw:LinksView DataContext="{Binding LinksVM}"/>
<ContentControl Content="{Binding CurrentUserControl}" />
</StackPanel>
LinksView.xaml
<StackPanel Orientation="Vertical">
<Button Content="Company" Width="75" Margin="3" Command="{Binding BtnCompanyClickCommand}" />
</StackPanel>
since LinksView is explicitly created in MainWindow, there is no need in DataTemplate - it can be removed
<DataTemplate DataType="{x:Type vm:LinksViewModel}">
<vw:LinksView />
</DataTemplate>

Assigning ViewModels to UserControls at runtime and at design time

I am writing some data visualization code in WPF with MVVM Light. Here's a fragment:
<Window x:Class="EventBlockVisualization.MainWindow"
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"
xmlns:ignore="http://www.ignore.com"
Title="MainWindow"
mc:Ignorable="d ignore"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Window.Resources>
<ItemsPanelTemplate x:Key="GraphRowItemsPanelTemplate">
<StackPanel IsItemsHost="True" Orientation="Horizontal"/>
</ItemsPanelTemplate>
</Window.Resources>
<Grid IsSharedSizeScope="True">
<ScrollViewer Margin="8" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.CanContentScroll="True">
<ItemsControl x:Name="GraphItemsControl" Margin="8" ItemsSource="{Binding VibeEvents, Mode=OneTime}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="NameWidthSizeGroup" Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="NameTextBlock" Text="{Binding Name}" Grid.Column="0" Margin="4,0"/>
<ItemsControl x:Name="GraphRowItemsControl" ItemsSource="{Binding VibeEventViewModels, Mode=OneTime}" ItemsPanel="{DynamicResource GraphRowItemsPanelTemplate}" Grid.Column="1" Margin="4,0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" VerticalAlignment="Center" Height="10">
<TextBlock x:Name="FGTitleTextBox" Text="{Binding FGTitle}" Visibility="Collapsed"/>
<Button Margin="1,0,0,0" Width="{Binding LengthInSeconds}" HorizontalAlignment="Left" Background="{Binding BackgroundColor}" BorderBrush="#FF2186A1">
<Button.ToolTip>
<ToolTip>
<StackPanel>
<TextBlock FontWeight="Bold" Text="{Binding FGTitle}"/>
<TextBlock Text="{Binding LengthText}"/>
</StackPanel>
</ToolTip>
</Button.ToolTip>
</Button>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</Window>
I'd like to swap out the central ItemsControl.ItemTemplate DataTemplate and make it a User Control so that I can design it more easily in Expression Blend.
I cannot find a simple sample that includes a User Control in MVVM Light but there are some tutorial articles. For example in MVVM Instantiation Approaches (Option 6) Paul Stovell suggests binding in the UserControl's ViewModel in MVVM Light thus:
<UserControl ...>
<UserControl.Resources>
<ViewModelLocator x:Key="ViewModelLocator"/>
</UserControl.Resources>
<TextBox Text="{Binding Source={DynamicResource ViewModelLocator}, Path=CalculatorViewModel...}" />
That would work great when I'm designing the UserControl in Expression Blend as the locator can supply a ViewModel replete with dummy data. But what happens at runtime; how does that binding get overwritten with instances of the UserControl's ViewModel class supplied by collections in the main ViewModel? The same problem happens for the MainWindow at design time. If I am working in Expression Blend on the look and feel of the MainWindow how does that binding get overwritten with instances of the UserControl's ViewModel class supplied by collections in the design time main ViewModel?
There are a number of questions and answers that already touch on this:
In https://stackoverflow.com/a/3334780/575530 akjoshi suggests that the main ViewModel holds the instance of the UserControl's ViewModel; but how does that work when I am designing the UserControl itself?
In https://stackoverflow.com/a/9910298/575530 tam points out that "you want to keep your datacontext open and available for binding to in controls where you are using this control" and in the following comment SoMoS adds that one needs to "create properties in the ViewModel for the binded properties and when someone wants to change one property of the control (like some subcontrol enabled) he will have to go thru the View Model". That's promissing but I am not sure what to do in place of the MainViewModel's bindable collection of UserControlViewModels.
In https://stackoverflow.com/a/6340668/575530 Ehsan Ershadi suggests that "it's not a good idea to use MVVM Light ViewModelLocator for UserControles because it is a static property and when you are going to instantiate multiple instances of your user control there are going to have the same common ViewModel so they all act same and this is not what we want for a UserControl in case you decide to use it once in your entire project." And then states that "to get around this problem you need to modify the ViewModelLocator by making all the properties Non static for instance". I'm not sure how that would help me.
In the comments after https://stackoverflow.com/a/2637830/575530 Jon Mitchell mentions that "It does look like MVVM isn't ideal for creating user controls". I hope that's not right.
In contrast, in When should I use a UserControl instead of a Page? dthrasher mentions that "many of the WPF MVVM frameworks seem to avoid using the NavigationWindow and Page controls in favor of composing pages using nested UserControls", i.e. that UserControls are commonplace devices in MVVM.
In https://stackoverflow.com/a/1798649/575530 Reed Copsey reminds sandbox that "UserControls can always talk to their containing control via exposing properties and using DataBinding. This is very nice, since it preserves the MVVM style in all aspects." and that "The containing control can use properties to link two properties on two user controls together, again, preserving clean boundaries" But again I don't see how this helps when I am in Expression Blend designing the UserControl.
In Should I be using UserControls for my Views instead of DataTemplates? Rachel mentions occasionally using Expression Blend to design the UserControl before cutting and pasting the code into a DataTemplate: "in the event I do want to use it to design a DataTemplate, I usually create a new UserControl, design it the way I want it, then copy/paste the contents into a DataTemplate"
Sorry about this essay length question! I am confused about how to use MVVM Light when designing a UserControl destined to be the visual for the items in a collection on the MainWindow, especially how to set up the three bindings: run-time view models, design time view models for the main window and its instantiations of the user control, and a design time view model for the user control in isolation.
I think you're overcomplicating things:
What's wrong with:
<Grid IsSharedSizeScope="True">
<ScrollViewer Margin="8" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.CanContentScroll="True">
<ItemsControl x:Name="GraphItemsControl" Margin="8" ItemsSource="{Binding VibeEvents, Mode=OneTime}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<MyShinyUserControl DataContext={Binding}/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
Bind each VibeEvent to the DataContext of the user control. In the user control itself I'd suggest creating a design-time DataContext to make design easier. Design-Time DataContext looks like this:
<UserControl x:Class="EMC.Windows.AlarmsModule.UserControl1"
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"
mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:AlarmsModule="clr-namespace:EMC.Windows.AlarmsModule" d:DesignHeight="300"
d:DesignWidth="300"
d:DataContext="{d:DesignInstance Type=AlarmsModule:Alarm}"
>
This gets you to a place where you can build your user control and have design-time data in it. And it's simple and doesn't require much, if any, scaffolding.
Based on Faster Solutions' answer here's the simplest example I can come up with of using a UserControl to display the contents of a list within MVVM Light.
For completeness sake I'll include all the code which I have tried to make as short as possible while still providing design time data that differs from run time data in both the user control's view model and the main view model.
Firstly the locator, VMUCExample/ViewModel/ViewModelLocator.cs:
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;
namespace VMUCExample.ViewModel
{
public class ViewModelLocator
{
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<MainViewModel>();
SimpleIoc.Default.Register<ASquareViewModel>();
}
public ASquareViewModel ASquare
{
get
{
return ServiceLocator.Current.GetInstance<ASquareViewModel>();
}
}
public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
}
public static void Cleanup() {}
}
}
I've not used the data service side of MVVM Light, partly to keep things simple. The visible distinction between live data and design time data is handled in the two view model classes.
VMUCExample/ViewModel/ASquareViewModel.cs:
using System.Windows.Media;
using GalaSoft.MvvmLight;
namespace VMUCExample.ViewModel
{
public class ASquareViewModel : ViewModelBase
{
private Brush _SquareColour;
public Brush SquareColour
{
get
{
return _SquareColour ?? (_SquareColour = IsInDesignModeStatic ?
new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0x78, 0x78)) : // FF7878 (pastel red)
new SolidColorBrush(Color.FromArgb(0xFF, 0xFF, 0xBB, 0x78))); // FFBB78 (nectarine)
}
set { _SquareColour = value; }
}
}
}
So looking at the user control in Expression Blend I see a simple rectangle with pastel red fill:
The main view model lives in the file VMUCExample/ViewModel/MainViewModel.cs:
using System.Collections.Generic;
using System.Windows.Media;
using GalaSoft.MvvmLight;
namespace VMUCExample.ViewModel
{
public class MainViewModel : ViewModelBase
{
private List<ASquareViewModel> _Squares;
public List<ASquareViewModel> Squares
{
get
{
if (_Squares == null)
{
_Squares = new List<ASquareViewModel>();
var colour = IsInDesignModeStatic ?
new SolidColorBrush(Color.FromArgb(0xFF, 0x78, 0xB2, 0xFF)) : // 78B2FF (pastel blue)
new SolidColorBrush(Color.FromArgb(0xFF, 0xF9, 0xFF, 0xC7)); // F9FFC7 (eggshell)
for (var i = 0; i < 10; i++)
{
_Squares.Add(new ASquareViewModel {SquareColour = colour});
}
}
return _Squares;
}
set { _Squares = value; }
}
public MainViewModel() {}
}
}
The view for this can also be edited in Expression Blend, but the view model code sets the design time colour data differently:
These are the two XAML files, firstly VMUCExample/ASquareUC.xaml:
<UserControl x:Class="VMUCExample.ASquareUC"
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" d:DesignHeight="15" d:DesignWidth="60"
d:DataContext="{Binding ASquare, Mode=OneWay, Source={StaticResource Locator}}">
<Grid>
<Rectangle Fill="{Binding SquareColour}" Margin="2" Width="50" Height="10"/>
</Grid>
</UserControl>
You can see I've used Faster Solutions' suggestion of putting d:DataContext so that the design time binding I need for Expression Blend when I am designing the user control does not block the data context I need at run-time nor the data context supplied by the parent when I am designing the main window in Expression Blend. I am uncomfortable about this though, it is not the approach characterised as MVVM Light in Paul Stovell's Option 6: A XAML View Model Locator and endorsed by #LBugnion
The other view file is VMUCExample\MainWindow.xaml:
<Window x:Class="VMUCExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vmucExample="clr-namespace:VMUCExample"
Height="200" Width="100"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Grid x:Name="LayoutRoot">
<ScrollViewer ScrollViewer.CanContentScroll="True">
<ItemsControl ItemsSource="{Binding Squares}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<vmucExample:ASquareUC/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</Window>
The example application itself just draws ten rectangles in a column:
Too simple, I know, but hopefully shows the three potential data sets in use:
Design time for the user control (#FF7878 pastel red),
Design time for the user control set by the main window (#78B2FF pastel blue), and
Run time for the user control set by the main window (#F9FFC7 eggshell).
(N.B. There is another data option, run time for the user control not set by the main window. In this case the user control's view model chooses #FFBB78/nectarine but I didn't need that to explore these bindings.)
For completeness here is the VMUCExample\App.xaml file:
<Application x:Class="VMUCExample.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:VMUCExample.ViewModel"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
StartupUri="MainWindow.xaml"
mc:Ignorable="d">
<Application.Resources>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
</Application.Resources>
</Application>

Silverlight - Setting DataContext in XAML rather than in constructor?

How can I set the DataContext on my Grid in XAML, instead of in the constructor?
Here is how I do it in the constructor (LayoutRoot is the XAML Grid defined in the XAML):
this.LayoutRoot.DataContext = this.HPVM;
I would prefer to do it right in the XAML, but I do not know how to reference the HPVM object in XAML. HPVM is a public property on the USerControl class.
It works fine as listed above, but again, I just want to know how to properties of the UserControl class in XAML, rather than always having to do it in code.
Here is all the relevant code:
<UserControl x:Class="SilverlightApplication1.SLHolePattern" x:Name="HolePatternsControl"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:controls="clr-namespace:Microsoft.Windows.Controls;assembly=Microsoft.Windows.Controls"
xmlns:local="clr-namespace:SilverlightApplication1"
xmlns:GeoPatterns="clr-namespace:GeoPatterns"
Height="700">
<UserControl.Resources>
...
And here is my constructor where the DataContext is currently set:
namespace SilverlightApplication1
{
public partial class SLHolePattern : UserControl, INotifyPropertyChanged
{
public HolePatternsViewModel HPVM;
public SLHolePattern()
{
InitializeComponent();
this.HPVM=new HolePatternsViewModel();
this.LayoutRoot.DataContext = this.HPVM;
...more code here
}
It all works fine, but I just want to learn how to set the DataContext in XAML, not in code.
The answer Chris gave works just fine.
I have tested and it worked for me.
You can instantiate your class in XAML (within the UserControl.Resources) and
then bind the datacontext to a static resource.
Follow code:
<UserControl ...>
<UserControl.Resources>
<myNS:MyClass x:Name="TheContext" x:Key="TheContext"></myNS:MyClass>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White" DataContext="{StaticResource TheContext}" >
<TextBlock Text="{Binding Path=Field1}">
</TextBlock>
</Grid>
</UserControl>
The following monstrosity works in Silverlight 4
<UserControl
DataContext="{Binding HPVM, RelativeSource={RelativeSource Self}}">
<UserControl.DataContext>
<vm:ThisUCViewModel />
</UserControl.DataContext>
try something like this.....
<Grid DataContext="{Binding Path=HPVM}">
</Grid>
where HPVM is a public member of this--> your form etc.
Create the instance of your class in the xaml, by adding something like this to your resources section.... (don't forget to add your xmlns namespace)
<my:bogart x:Key="franken"/>
then, bind the data context to the static resource you just added....
<Grid x:Name="LayoutRoot" Background="White" DataContext="{StaticResource franken}">
<TextBox Background="Red" Foreground="White" Text="{Binding Path=sum}" />
</Grid>
In Silverlight 4, I was able to get this working by doing the following:
Give the Page/UserControl an x:Name="myPage"
In your control binding use normal Element bidning syntax. In my case I want to bind to an observable collection of objects in my code behind for my ItemsSource property:
<ComboBox
ItemsSource={Binding ElementName=myPage, Path=MyObservableObjectList, Mode=TwoWay}
I haven't tried this with DataContext but know you can do element to element binding for DataContext as I do this for Grids whose context is based on the selected item of some other drop down on the page.
This is not possible (It is possible in WPF with {Binding RelativeSource={RelativeSource Self}}, but Silverlight is more limited.
You have to do it through code.
<UserControl.Resources>
<ResourceDictionary>
<vm:YourModelx:Key="myModel"/>
</ResourceDictionary>
</UserControl.Resources>
<UserControl.DataContext>
<Binding Source="{StaticResource myModel}"/>
</UserControl.DataContext>

Resources