Why is binding for a Caliburn.Micro UserControl
enclosed to WPF User Control Library not working with ContentControl
?
Initial
Create new Wpf App v4.6.2
- Install Nuget Caliburn.Micro v3.1.0
- Install Nuget Caliburn.Micro.Start v3.1.0
- Do adaptions like explained http://caliburnmicro.com/documentation/nuget
- adapt app.xaml
- delete StartupUri
- add ResourceDictionary
- check AppBootstrapper
- delete MainWindow.xaml
- Add Button
x:Name="DoIt"
to ShellView.xaml - Add
public void DoIt()
with MessageBox.Show() to ShellViewModel.cs - Test this initial version
✓ Check! This runs and binding works...
UserControl View
- Add
UserControl
and name it e.g. TestUcView - Add a
Textbox
and give a name e.g. UcValue
<UserControl x:Class="WpfApp1.Test2UcView"
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:WpfApp1"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="200" Visibility="{Binding UcVisibility}">
<Grid >
<TextBox x:Name="UcValue" HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="100"/>
<Button x:Name="UcAction" Content="Do specific" HorizontalAlignment="Left" Margin="120,10,0,0" VerticalAlignment="Top" Width="75"/>
</Grid>
</UserControl>
UserControl ViewModel
- Add class with corresponding name TestUcViewModel
- Change class to public and derive from screen and add using Caliburn.Micro
- Add property with corresponding name to
TextBox
e.g. UcValue
public class Test1UcViewModel : Screen
{
private string _UcValue;
public string UcValue { get => _UcValue; set { _UcValue = value; NotifyOfPropertyChange(() => UcValue); } }
public void TestBut2() {
MessageBox.Show("TestBut2");
}
}
UserControl Integration
- In ShellViewModel create public property for the ViewModel and create an instance in the constructor
Create control in View to be bound
- Possibility: Place
ContentControl
in theShellView.xaml
with the same Name as the ViewModel property (ViewModel first) - Possibility: Compile and place the
UserControl
into theShellView.xaml
and addcal:Bind.Model="{Binding <ViewModel-Property-Name>}"
for this the namespace
- Possibility: Place
✓ Check! This runs and binding of UserControl works...
BUT,
...now with integrating the third UserControl
that belongs to a WPF User Control Library (dll), the Caliburn binding doesn't work for the UserControl
from the dll when using the syntax for ContentControl
.
public class ShellViewModel : Caliburn.Micro.PropertyChangedBase, IShell
{
private Test1UcViewModel _Test1UserControlModel;
private Test2UcViewModel _Test2UserControlModel;
private Test3UcViewModel _Test3UserControlModel;
public Test1UcViewModel Test1 { get => _Test1UserControlModel; set { _Test1UserControlModel = value; NotifyOfPropertyChange(() => Test1); } }
public Test2UcViewModel Test2 { get => _Test2UserControlModel; set { _Test2UserControlModel = value; NotifyOfPropertyChange(() => Test2); } }
public Test3UcViewModel Test3 { get => _Test3UserControlModel; set { _Test3UserControlModel = value;NotifyOfPropertyChange(() => Test3); } }
public ShellViewModel()
{
_Test1UserControlModel = new Test1UcViewModel();
Test1.UcValue = "Bubble";
_Test2UserControlModel = new Test2UcViewModel();
Test2.UcValue = "Simmer";
_Test3UserControlModel = new Test3UcViewModel();
Test3.Uc3Value = "Knocking on heavens door";
Test1.UcVisibility = Visibility.Visible;
Test2.UcVisibility = Visibility.Hidden;
Test3.UcVisibility = Visibility.Hidden;
}
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="http://www.caliburnproject.org"
xmlns:local="clr-namespace:WpfApp1"
xmlns:TestUcLib="clr-namespace:TestUcLib;assembly=TestUcLib"
x:Class="WpfApp1.ShellView" Width="500" Height="300">
<Grid Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Input"
TextWrapping="Wrap"
VerticalAlignment="Bottom"
HorizontalAlignment="Center"
FontSize="20" />
<StackPanel>
<Button x:Name="DoIt1" Content="Do it 1" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="5"/>
<Button x:Name="DoIt2" Content="Do it 2" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="5"/>
<Button x:Name="DoIt3" Content="Do it 3" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="5"/>
</StackPanel>
<ContentControl x:Name="Test1" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
<ContentControl x:Name="Test2" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
<ContentControl x:Name="Test3" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
<!--This one works-->
<!--<TestUcLib:Test3UcView cal:Bind.Model="{Binding Test3}" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>-->
</Grid>
</Window>
Is it mandatory to use <TestUcLib:Test3UcView cal:Bind.Model="{Binding Test3}"
instead of using ContentControl when the UserControl is inside dll?