User control's dependency property not binding - c#

I have user control with dependency property. When I try bind it in windows it doesn't work. But when I change binding to normal parameter (in this situation, true) it's working. What i need to do to make my binding working? Maybe something with DataContext? Here is my code:
First user control's xaml:
<UserControl x:Class="DPTest.CustomUserControl"
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"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="100" d:DesignWidth="200"
DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}">
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<TextBlock Text="{Binding Property}"/>
</Grid>
</UserControl>
Code behind:
public partial class CustomUserControl : UserControl, INotifyPropertyChanged
{
public static readonly DependencyProperty DPTestProperty = DependencyProperty.Register("DPTest", typeof(bool), typeof(CustomUserControl), new PropertyMetadata(default(bool), propertyChangedCallback));
public bool DPTest
{
get
{
return (bool)GetValue(DPTestProperty);
}
set
{
SetValue(DPTestProperty, value);
}
}
private bool _property;
public bool Property
{
get
{
return _property;
}
set
{
_property = value;
RaisePropertyChanged("Property");
}
}
private static void propertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = d as CustomUserControl;
control.Property = (bool)e.NewValue;
}
public CustomUserControl()
{
InitializeComponent();
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
In the windows where i put this user control data context is set to my view model:
<phone:PhoneApplicationPage
x:Class="DPTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:my="clr-namespace:DPTest"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
<TextBlock Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<my:CustomUserControl Name="cstom" DPTest="{Binding Property}"/>
</Grid>
</Grid>
</phone:PhoneApplicationPage>
In the view model I have property which is binded to DPTest.
public class MainViewModel : ViewModelBase
{
private bool _property;
public bool Property
{
get { return _property; }
set
{
_property = value;
RaisePropertyChanged("Property");
}
}
public MainViewModel()
{
Property = true;
}
}
When I run this application Textblock have value False but this should be True and propertyChangedCallback isn't even called. What i need to do?
Thanks

Try this:
<UserControl x:Class="DPTest.CustomUserControl"
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" mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource
PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" d:DesignHeight="100"
d:DesignWidth="200"
x:Name="self">
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<TextBlock Text="{Binding Property, ElementName=self}"/>
</Grid>

You have bind UserControl DataContext to itself since you want to bind Property present in CustomUserControl to TextBlock inside it which is completely fine.
But when you use CustomUserControl in Window, it won't inherit Window's DataContext since its explicitly set on UserControl declaration. So, binding engine is trying to look for property in UserControl which it can't fine.
Note: Binding engine looks for property inside it's DataContext otherwise instructed to look somewhere else using RelativeSource, ElementName, x:Reference etc.
So you need to manually provide binding engine the property instance like this:
<my:CustomUserControl Name="cstom"
DPTest="{Binding Path=DataContext.Property,
ElementName=LayoutRoot}"/>
Explanation for working with DPTest="True":
Since you already manually provided the value to DP, binding engine doesn't have to worry about finding it in DataContext.

Related

Data Binding to User Control Error Data.Binding cannot be converted to System.String

I'm new to WPF and I'm having trouble binding text to a user control I made. It's a simple control, it's just basically a button with text and a image that I want to reuse in several Views.
Here is my User Control's .cs
public partial class MenuItemUserControl : UserControl
{
public string TextToDisplay { get; set; }
public MenuItemUserControl()
{
InitializeComponent();
DataContext = this;
}
}
Here is my User Control's xaml
<UserControl x:Class="Class.Controls.MenuItemUserControl"
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"
xmlns:local="clr-namespace:Class.Controls"
mc:Ignorable="d"
d:DesignHeight="83.33" d:DesignWidth="512">
<Grid>
<Button Style="{StaticResource MenuItemStyle}" Height="Auto" Width="Auto">
<DockPanel LastChildFill="True" Width="512" Height="83.33" HorizontalAlignment="Center" VerticalAlignment="Center">
<Image Source="/Resources/MenuArrow.png" Stretch="None" HorizontalAlignment="Left" VerticalAlignment="Center" DockPanel.Dock="Left"/>
<TextBlock d:Text="sample" Text="{Binding TextToDisplay, Mode=OneWay}" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="{StaticResource MenuItems}"/>
</DockPanel>
</Button>
</Grid>
</UserControl>
Here is my View xaml
<Page x:Class="Class.Views.MenuOperate"
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"
xmlns:uc="clr-namespace:Class.Controls"
xmlns:local="clr-namespace:Class.Views"
xmlns:properties="clr-namespace:Class.Properties"
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls" xmlns:viewmodels="clr-namespace:Class.ViewModels" d:DataContext="{d:DesignInstance Type=viewmodels:MenuOperateViewModel}"
mc:Ignorable="d"
d:DesignHeight="500" d:DesignWidth="1024"
Title="MenuOperate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="83.33"/>
<RowDefinition Height="83.33"/>
<RowDefinition Height="83.33"/>
<RowDefinition Height="83.33"/>
<RowDefinition Height="83.33"/>
<RowDefinition Height="83.33"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="512"/>
<ColumnDefinition Width="512"/>
</Grid.ColumnDefinitions>
<uc:MenuItemUserControl TextToDisplay="{Binding StartStop, Mode=TwoWay}" Grid.Row="0" Grid.Column="0"/>
</Grid>
</Page>
Here is my View Model .cs
namespace Class.ViewModels
{
public class MenuOperateViewModel : ObservableObject
{
private string? _StartStop;
public MenuOperateViewModel()
{
StartStop = Properties.Resources.MenuOperateStart;
}
public string? StartStop
{
get => _StartStop;
set => SetProperty(ref _StartStop, value);
}
}
}
This is the error I get in my View Xaml:
Object of Type 'System.Windows.Data.Binding' cannot be converted to type 'System.String'.
There are two things that prevent that the expression
TextToDisplay="{Binding StartStop}"
works.
The target property of the Binding, i.e. TextToDisplay must be a dependency property.
You must not explicity set the UserControl's DataContext. The Binding will resolve the source property path relative to the current DataContext, i.e. with DataContext = this; in the control's constructor, it expects the source property StartStop on the UserControl, which is obviously wrong.
For details, see Data binding overview
Your code should look like this:
public partial class MenuItemUserControl : UserControl
{
public static readonly DependencyProperty TextToDisplayProperty =
DependencyProperty.Register(
nameof(TextToDisplay),
typeof(string),
typeof(MenuItemUserControl));
public string TextToDisplay
{
get { return (string)GetValue(TextToDisplayProperty); }
set { SetValue(TextToDisplayProperty, value); }
}
public MenuItemUserControl()
{
InitializeComponent();
}
}
The Binding in the UserControl's XAML would then use a RelativeSource Binding.
<TextBlock Text="{Binding TextToDisplay,
RelativeSource={RelativeSource AncestorType=UserControl}}" />

UserControl background property Brush binding does not work

Hello i am trying to initialize usercontrol with bacground which is binded in viewmodel. In model color is set but dependency property does not take it.
HeaderCropper xaml :
<UserControl x:Class="x.CustomControls.x"
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"
xmlns:converters="clr-x.Converters"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300"
Width="{Binding CropperWidth,ElementName=HeaderCropper}"
Height="{Binding CropperHeight,ElementName=HeaderCropper}"
x:Name="HeaderCropper">
<Thumb x:Name="CroppableArea" BorderThickness="1" Grid.Column="0" Grid.Row="0" Background='{Binding CropperColor}' BorderBrush="Black" Opacity="0.2"
HeaderCropper class :
public static DependencyProperty ColorProperty;
static HeaderCroper()
{
ColorProperty = DependencyProperty.Register("CropperColor",
typeof(Brush), typeof(HeaderCroper), new FrameworkPropertyMetadata(null));
}
public Brush CropperColor
{
get { return (Brush)GetValue(ColorProperty); }
set
{
SetValue(ColorProperty, value);
}
}
HeaderCropper binding :
<DataTemplate>
<custom:HeaderCroper Panel.ZIndex="1" Width="50" Height="50" CropperHeight="{Binding Height,Mode=TwoWay,NotifyOnTargetUpdated=True}"
CropperWidth="{Binding Width,Mode=TwoWay,NotifyOnTargetUpdated=True}"
MaxCropperHeight="{Binding ElementName=Image,Path=RenderSize.Height}"
MaxCropperWidth="{Binding ElementName=Image,Path=RenderSize.Width}"
InfoCommand="{Binding InfoCommand}"
InfoCommandParameter="{Binding Id}"
DeleteCropperCommand="{Binding DeleteCommand}"
DeleteCropperCommandParameter="{Binding Id}"
CropperLeft="{Binding CropperLeft,Mode=TwoWay,NotifyOnTargetUpdated=True}"
CropperTop="{Binding CropperTop,Mode=TwoWay,NotifyOnTargetUpdated=True}"
MainCanvas ="{Binding ElementName=CropperCanvas,NotifyOnTargetUpdated=True}"
Canvas.Left="0"
CropperColor="{Binding CropperColor,Mode=TwoWay,NotifyOnTargetUpdated=True}"
/>
</DataTemplate>
As you can see CropperColor parameter is passed but header cropper is ignoring it and not setting color. Any ideas?
UPDATE:
As I debug on private method key press I see that color is set but it is null while usercontroll is initializing.

Defining UserControl Properties and binding them in windows phone

In my windows phone application, I made a user control that has some text blocks and images. It's something like a control to show posts like Facebook. I want to use this user control in a long list selector, but whenever I try to bind data to it I get no data. Please help me.
This is the MainPage.xaml
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<phone:LongListSelector Name="myLLS">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<local:Posts TitleText={Binding TitleText}>
</local:Posts>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</Grid>
And this is the code behind
public class TestData
{
private string _TitleText;
public string TitleText
{
get { return _TitleText; }
set { _TitleText = value; }
}
public TestData(string Text)
{
This.TitleText = Text;
}
}
And this is the UserControl xaml code
<UserControl x:Class="BindingUserControlTest.TestBind"
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"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}" Height="125.889" Width="227.974">
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<TextBlock x:Name="lblTitle" HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top"/>
<TextBlock x:Name="lblDescription" HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Margin="0,32,0,0" Width="218" Height="84"/>
</Grid>
And this is the code behind :
private string _ShownTitle;
public string ShownTitle { get { return _ShownTitle; } set { _ShownTitle = value; }}
You need to use DependencyProperties to be able to bind to an attribute. Rather than re-write the code for you, I will give you a link to a blog by Jerry Nixon, who explains the process well.
http://blog.jerrynixon.com/2013/07/solved-two-way-binding-inside-user.html
EDIT:
Code Behind for the Usercontrol would look like.
public sealed partial class ExampleControl : UserControl
{
public static readonly DependencyProperty exampleProperty = DependencyProperty.Register("ExampleData", typeof(Double), typeof(NutritionLabelControl), null);
public ExampleControl()
{
InitializeComponent();
(this.Content as FrameworkElement).DataContext = this;
}
public Double ExampleData
{
get { return (Double)GetValue(exampleProperty); }
set
{
SetValue(exampleProperty, value);
}
}
}
Then in your userControls XAML you would have something like:
<UserControl>
<Grid x:Name="LayoutRoot">
<TextBlock Text="{Binding ExampleData}" />
</Grid>
</UserControl>
You can then use the same Binding format in the MainPage.xaml as in the usercontrols XAML.

Binding ContentControl to a View for a ViewModel

I'm using MVVM in a windows phone 8 application. I would like to move from 1 view model to another inside my shell view model. I can't seem to get the ContentControl to bind to a template that is a usercontrol/phoneApplicationPage over the view model.
What am I missing?
I'm trying to avoid things like MVVM light. (I want my app to be as small a download as possible) And this should be possible to do.
P.S. I'm still pretty new to WPF/WP8
Here is a sample of what I have so far, Excuse the dumb functionality :)
/** The Shell view **/
<phone:PhoneApplicationPage
x:Class="PhoneAppWithDataContext.Navigation.ViewModelNavigation"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d"
shell:SystemTray.IsVisible="True"
xmlns:vm="clr-namespace:PhoneAppWithDataContext.Navigation">
<phone:PhoneApplicationPage.DataContext>
<vm:AppViewModel/>
</phone:PhoneApplicationPage.DataContext>
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="MonthViewModel">
<vm:MonthViewControl/>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ContentControl Content="{Binding CurrentViewModel}"
ContentTemplate="{Binding ContentTemplate}"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"/>
</Grid>
<Button Content="Change VM" Command="{Binding ChangeViewModelCommand}"/>
</Grid>
</phone:PhoneApplicationPage>
/** Shell/Application View Model **/
public class AppViewModel : ViewModelBase
{
private ViewModelBase _currentViewModel;
private List<ViewModelBase> _viewModels = new List<ViewModelBase>();
private byte _month = 1;
public ViewModelBase CurrentViewModel
{
get
{
return _currentViewModel;
}
set
{
if (_currentViewModel == value)
return;
_currentViewModel = value;
NotifyPropertyChanged("CurrentViewModel");
}
}
public DataTemplate SelectedTemplate
{
get
{
if (_currentViewModel == null)
return null;
return DataTemplateSelector.GetTemplate(_currentViewModel);
}
}
public List<ViewModelBase> ViewModels
{
get
{
return _viewModels;
}
}
public AppViewModel()
{
ViewModels.Add(new MonthViewModel(_month));
CurrentViewModel = ViewModels.FirstOrDefault();
}
private ICommand _changeViewModelCommand;
public ICommand ChangeViewModelCommand
{
get
{
return _changeViewModelCommand ?? (_changeViewModelCommand = new GenericCommand(() =>
{
_month++;
var newVM = new MonthViewModel(_month);
ViewModels.Add(newVM);
CurrentViewModel = newVM;
}, true));
}
}
private void ChangeViewModel(ViewModelBase viewModel)
{
if (!ViewModels.Contains(viewModel))
ViewModels.Add(viewModel);
CurrentViewModel = ViewModels.FirstOrDefault(vm => vm == viewModel);
}
}
/** DataTemplateSelector **/
public static class DataTemplateSelector
{
public static DataTemplate GetTemplate(ViewModelBase param)
{
Type t = param.GetType();
return App.Current.Resources[t.Name] as DataTemplate;
}
}
/** User Control **/
<UserControl x:Class="PhoneAppWithDataContext.Navigation.MonthViewControl"
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"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="480" d:DesignWidth="480"
xmlns:vm="clr-namespace:PhoneAppWithDataContext.Navigation">
<UserControl.DataContext>
<vm:MonthViewModel/>
</UserControl.DataContext>
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Id" Width="100" VerticalAlignment="Center" Grid.Row="0" Grid.Column="0" />
<TextBlock Text="{Binding Id}" Width="100" VerticalAlignment="Center" Grid.Row="0" Grid.Column="1" />
<TextBlock Text="Name" Width="100" VerticalAlignment="Center" Grid.Row="1" Grid.Column="0" />
<TextBlock Text="{Binding Name}" Width="100" VerticalAlignment="Center" Grid.Row="1" Grid.Column="1" />
</Grid>
</UserControl>
/** ViewModelBase **/
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
/** View model that the user control should bind to **/
public sealed class MonthViewModel : ViewModelBase
{
private byte _id;
private string _name;
public MonthViewModel()
{
}
public MonthViewModel(byte id)
{
_id = id;
_name = "Month " + id.ToString() + " of the year";
}
public override string ToString()
{
return _name;
}
public byte Id
{
get
{
return _id;
}
}
public string Name
{
get
{
return _name;
}
}
}
I believe the problem here is:
<UserControl.DataContext>
<vm:MonthViewModel/>
</UserControl.DataContext>
When your Content is changed from one MonthViewModel to the next, the DataContext of the returned DataTemplate is set to the object bound to Content. Well, once that DataContext is set, you should be good to go, but once the UserControl is loaded, it is resetting the DataContext to a new instace of an empty MonthViewModel (vm:MonthViewModel). Get rid of that explicit DataContext declaration--in other words delete the code that I posted above.
That way, when you first call CurrentViewModel and INPC is raised, it won't reset the DataContext. When you switch between CurrentViewModel's that are of MonthViewModel type, your UserControl won't call InitializeComponent again, instead the DataContext will change.
EDIT
In addition, if you still aren't seeing changes, then I would point to SelectedTemplate property. Instead of the null check in the property, just pass null to the GetTemplate. Inside of GetTemplate, check for null and return null there if it is null.

Add a usercontrol to caliburm micro dynamically

I am using Caliburn Micro with WPF. I want to create an application with a menu on the left side, and a grid on the right side of the application. When clicking on a menu item, the grid on the right side, will change to another view. The another view will be in a separate file.
MainWindowView:
<UserControl x:Class="CMDemo.Views.MainWindowView"
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="300" d:DesignWidth="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="90*" />
<ColumnDefinition Width="210*" />
</Grid.ColumnDefinitions>
<StackPanel Name="LeftMenu">
<Button Name="ChangeDisplay" Content="Click Me"></Button>
<TextBlock x:Name="MyString"></TextBlock>
</StackPanel>
<Grid Grid.Column="1" x:Name="MainGridContent" />
</Grid>
MainWindowViewModel:
public class MainWindowViewModel : PropertyChangedBase
{
private UserControl mainGridContent;
private string myString;
public UserControl MainGridContent
{
get { return this.mainGridContent; }
set
{
this.mainGridContent = value;
NotifyOfPropertyChange(() => this.MainGridContent);
}
}
public string MyString
{
get { return this.myString; }
set
{
this.myString = value;
NotifyOfPropertyChange(() => this.MyString);
}
}
public void ChangeDisplay()
{
this.MainGridContent = new ChangeDisplayView();
this.MyString = "Testing....";
}
}
The changeDisplayViewModel:
public class changeDisplayViewModel: PropertyChangedBase
{
}
The changeDisplayView:
<UserControl x:Class="CMDemo.Views.changeDisplayView"
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="300" d:DesignWidth="300">
<Grid>
<TextBox content="Hello Caliburn Micro">
</Grid>
When I click the "Click Me" button the TextBlock "MyString" is updated and showing, but the usercontrol is not. What am I doing wrong?
Try changing MainGridContent to a changeDisplayViewModel rather than the view itself.

Categories

Resources