Reputation: 1003
How to bind/create MetroWindow.RightWindowCommands in dynamically created MetroWindow through Caliburn.Micro IWindowManager Show method?
For example, I've created a custom IWindowManager implementation to always create MetroWindow instead of default Window. So whenever a new Window is created from Caliburn, it will be MetroWindow instance.
I have a logic that creates dynamically windows through IWindowManager:
ChatManager
public class ChatManager : IChatManager
{
private readonly IChatWindowSettings chatWindowSettings;
private readonly IWindowManager windowManager;
private readonly IChatFactory chatFactory;
private IDictionary<WeakReference, WeakReference> chats;
public ChatManager(IChatWindowSettings chatWindowSettings, IWindowManager windowManager, IChatFactory chatFactory)
{
this.chatWindowSettings = chatWindowSettings;
this.windowManager = windowManager;
this.chatFactory = chatFactory;
chats = new Dictionary<WeakReference, WeakReference>();
}
public void OpenFor(ISender sender)
{
var settings = chatWindowSettings.Create();
var viewModel = CreateOrGetViewModel(sender);
windowManager.ShowWindow(viewModel, null, settings);
}
private IChat CreateOrGetViewModel(ISender sender){//code...}
Those windows are chat windows. This works great. However, I'd like to bind/create a button directly in the MetroWindow RightCommands. This button would be bound to the IChat implementation (which is a view-model):
public class ChatViewModel : Screen, IChat
{
public void DoSomething(){}
}
How can I accomplish such thing?
Upvotes: 1
Views: 1995
Reputation: 14611
here are some thoughts for your problem
calling sample
var view = new MainWindow(new ChatViewModel() { ChatName = "Chat name" });
view.Show();
model sample
public class ChatViewModel
{
public string ChatName { get; set; }
private ICommand chatCommand;
public ICommand ChatCommand
{
get
{
return chatCommand
?? (chatCommand = new SimpleCommand() {
CanExecutePredicate = o => true,
ExecuteAction = o => MessageBox.Show("Hurray :-D")
});
}
}
}
window code behind
public partial class MainWindow : MetroWindow
{
public MainWindow(ChatViewModel chatViewModel)
{
this.DataContext = chatViewModel;
InitializeComponent();
}
}
window xaml
<Controls:MetroWindow x:Class="MahAppsMetroSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="http://metro.mahapps.com/winfx/xaml/controls"
Title="MainWindow"
GlowBrush="{DynamicResource AccentColorBrush}"
Height="350"
Width="525">
<Controls:MetroWindow.RightWindowCommands>
<Controls:WindowCommands>
<Button Content="{Binding ChatName}"
Command="{Binding ChatCommand}" />
</Controls:WindowCommands>
</Controls:MetroWindow.RightWindowCommands>
<Grid>
<!-- the content -->
</Grid>
</Controls:MetroWindow>
simple command
public class SimpleCommand : ICommand
{
public Predicate<object> CanExecutePredicate { get; set; }
public Action<object> ExecuteAction { get; set; }
public bool CanExecute(object parameter)
{
if (CanExecutePredicate != null)
return CanExecutePredicate(parameter);
return true; // if there is no can execute default to true
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
if (ExecuteAction != null)
ExecuteAction(parameter);
}
}
hope that helps
Upvotes: 3