I'm trying to find a technique to show modal views from within other views but I am having problems. Here's a simple example of what i'm trying to do:
Shared ViewModel
class ClientesViewModel : Screen
{
private bool _deleteconfirmvisible;
public bool DeleteConfirmVisible
{
get { return _deleteconfirmvisible; }
set
{
_deleteconfirmvisible = value;
NotifyOfPropertyChange("DeleteConfirmVisible");
}
}
public void ShowDeleteConfirm()
{
this.DeleteConfirmVisible = true;
}
public ModalViewModel ModalDelete
{
get { return new ModalViewModel(); }
}
public void ConfirmDelete()
{
//Actually delete the record
//WCFService.DeleteRecord(Record)
}
}
First View
<UserControl x:Class="Ohmio.Client.ClientesView"
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:mahapps="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:local="clr-namespace:Ohmio.Client"
mc:Ignorable="d"
d:DesignHeight="364" d:DesignWidth="792">
<UserControl.Resources>
<DataTemplate DataType="{x:Type local:ModalViewModel}">
<local:ModalView/>
</DataTemplate>
</UserControl.Resources>
<local:ModalContentPresenter DataContext="{Binding}" IsModal="{Binding DeleteConfirmVisible}" Grid.ColumnSpan="5" Grid.RowSpan="4" ModalContent="{Binding Path=ModalDelete}">
<Grid>
<Button x:Name="ShowDeleteConfirm" Margin="5" Grid.Column="2" Content="Delete Record"/>
</Grid>
</local:ModalContentPresenter>
</UserControl>
Second View (Modal content)
<UserControl x:Class="Ohmio.Client.ModalView"
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:Ohmio.Client"
mc:Ignorable="d" Height="145" Width="476">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
</Grid.RowDefinitions>
<Label Content="Are you sure you want to delete this record?" Grid.ColumnSpan="2" HorizontalAlignment="Center" VerticalAlignment="Center"></Label>
<Button x:Name="ConfirmDelete" IsDefault="True" Grid.Row="2" Content="Aceptar" Margin="10"></Button>
<Button x:Name="TryClose" IsCancel="True" Grid.Row="2" Grid.Column="1" Content="Cancelar" Margin="10"></Button>
</Grid>
</UserControl>
ModalViewModel
class ModalViewModel : Screen
{
public ModalViewModel()
{
}
}
So the basic idea is to have two views that share the same viewmodel. This viewmodel has properties for showing the modal content and deleting the record.
The problema here is that ConfirmDelete
method is never called.I guess the problem is that the child views DataContext
is different from parent view. So How can I Solve this?
Thanks!
EDIT
Forgot to mention, i'm using Caliburn.Micro
EDIT 2
I follow Rachel suggest and divide the viewmodel. Still the problem pesist. Here is how my code looks like now:
TestViewModel
class TestViewModel :Screen
{
private bool _deleteconfirmvisible;
TestModalViewModel _modaldelete;
public TestViewModel()
{
_modaldelete = new TestModalViewModel();
}
public bool DeleteConfirmVisible
{
get { return _deleteconfirmvisible; }
set
{
_deleteconfirmvisible = value;
NotifyOfPropertyChange("DeleteConfirmVisible");
}
}
public void ShowDeleteConfirm()
{
this.DeleteConfirmVisible = true;
}
public TestModalViewModel ModalDelete
{
get { return _modaldelete; }
}
}
TestView
<UserControl x:Class="Ohmio.Client.TestView"
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:mahapps="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:local="clr-namespace:Ohmio.Client"
mc:Ignorable="d"
d:DesignHeight="364" d:DesignWidth="792">
<UserControl.Resources>
<DataTemplate DataType="{x:Type local:TestModalViewModel}">
<local:TestModalView/>
</DataTemplate>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="40"></RowDefinition>
</Grid.RowDefinitions>
<ContentPresenter Content="{Binding Path=ModalDelete}"></ContentPresenter>
<Button x:Name="ShowDeleteConfirm" Margin="5" Grid.Row="1" Content="Delete Record"/>
</Grid>
</UserControl>
TestModalViewModel
class TestModalViewModel : Screen
{
private Boolean _result;
public TestModalViewModel()
{
_result = false;
}
public void ConfirmAction()
{
_result = true;
TryClose();
}
public bool Result
{
get { return _result; }
}
}
TestModalView
<UserControl x:Class="Ohmio.Client.TestModalView"
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:Ohmio.Client"
mc:Ignorable="d" Height="145" Width="476">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Label Content="Are you sure you want to delete this record?" Grid.ColumnSpan="2" HorizontalAlignment="Center" VerticalAlignment="Center"></Label>
<Button x:Name="ConfirmAction" IsDefault="True" Grid.Row="2" Content="Aceptar" Margin="10"></Button>
<Button x:Name="TryClose" IsCancel="True" Grid.Row="2" Grid.Column="1" Content="Cancelar" Margin="10"></Button>
</Grid>
</UserControl>
I change the ModalContentPresenter for and ContentPresenter, and the problema remains: ConfirmAction is never called, and i can't understand why. Can anyone tell me why?
EDIT 3
Snoop Result:
Screen
that this is Caliburn Micro. Caliburn will magically bind the button to a method with the same name as the button. – RoathTestModelView
? – Chrismatory