Closed AzureKitsune closed 9 years ago
Off-Topic: issue number 999
Opening a Flyout is relatively complex in a MVVM scenario. For the record, how I did it in my project:
Works very nicely but you have to know how to use Caliburn's event aggregator.
Way to complicated ... especially for one that just begins using/learning MVVM ... :unamused:
Here are some code samples from my app to get you started, Note that this uses Caliburn.Micro
Interface common to all flyout viewmodels (probably best to make an abstract base class for convenience)
public interface IFlyout : IScreen
{
string Header { get; set; }
bool IsOpen { get; set; }
Position Position { get; set; }
string Name { get; set; }
bool IsModal { get; set; }
}
Flyout definiton in your MetroWindow:
<metro:MetroWindow.Flyouts>
<metro:FlyoutsControl Name="Flyouts">
<metro:FlyoutsControl.Template>
<ControlTemplate>
<Grid>
<ItemsPresenter />
</Grid>
</ControlTemplate>
</metro:FlyoutsControl.Template>
<metro:FlyoutsControl.ItemContainerStyle>
<Style BasedOn="{StaticResource {x:Type metro:Flyout}}"
TargetType="{x:Type metro:Flyout}">
<Setter Property="Header"
Value="{Binding Header}" />
<Setter Property="IsOpen"
Value="{Binding IsOpen}" />
<Setter Property="Position"
Value="{Binding Position}" />
<Setter Property="IsModal"
Value="{Binding IsModal}" />
</Style>
</metro:FlyoutsControl.ItemContainerStyle>
</metro:FlyoutsControl>
</metro:MetroWindow.Flyouts>
Inside your metro windows's viewmodel (e.g. shell):
#region Flyouts
public void ToggleFlyout(string name)
{
this.ApplyToggleFlyout(name);
}
public void ToggleFlyout(string name, Position position)
{
this.ApplyToggleFlyout(name, position);
}
public void ToggleFlyout(string name, bool isModal)
{
this.ApplyToggleFlyout(name, null, isModal);
}
public void ToggleFlyout(string name, Position position, bool isModal)
{
this.ApplyToggleFlyout(name, position, isModal);
}
protected void ApplyToggleFlyout(string name, Position? position = null, bool? isModal = null, bool? show = null)
{
Contract.Requires(name != null, "name cannot be null");
foreach (var f in this.flyouts.Where(x => name.Equals(x.Name)))
{
if (position.HasValue)
{
f.Position = position.Value;
}
if (isModal.HasValue)
{
f.IsModal = isModal.Value;
}
if (show.HasValue)
{
f.IsOpen = show.Value;
}
else
{
f.IsOpen = !f.IsOpen;
}
}
}
#endregion
Here's how to use caliburn attached messages to call the toggleflyout methods:
<MenuItem Header="APPLICATION">
<MenuItem Header="Settings..."
cal:Message.Attach="[Event Click] = [Action ToggleFlyout('settings', 'Left', 'true')]"></MenuItem>
<Separator></Separator>
<MenuItem Header="Exit"
cal:Message.Attach="ExitToDesktop"></MenuItem>
</MenuItem>
Here is my (possibly not constructive) input on this issue: MahApps.Metro is a UI library, we shouldn't care if the user uses MVVM, MVC, what-have-you. The End.
@flagbug :+1:
@flagbug if WPF developers in MS also thought so, then we never see controls with binding support and other cool features.
I'm with @flagbug, MA.M is an UI library and should be agnostic to any MVVM, MVC, whatever framework. @QuantumDeveloper: Every control should support binding, no doubt. Beyond that, do you have any practical suggestions how to make MA.M more MVVM friendly?
I guess, in order to combine the two worlds, the best would be to create a library MA.M + Caliburn.Micro
Can a contrib project be launched, now that MahApps is in v1.0 stage, that folks can start dumping what they've done to solve common problems in the MVVM space (e.g. showing a dialog via an IDialogManager) in some sort of way that makese sense?
I've started with my own (opiniated) MVVM library based on MahApps.Metro, see TinyLittleMvvm. It still lacks some documenation though.
Meantime, I've discovered Caliburn.Metro which seems to be a good start in this direction (Caliburn.Micro + MA.M)
link @papuashu ?
@dealproc Caliburn.Metro
@remcoros I might be missing something in here. Where do you specify the UserControl that should appear inside the Flyout? In case of multiple Flyouts, how do you specify that? Thanks
There are some things in our library that can be made for or improved for MVVM scenarios. We should try to figure out how to make those non-friendly sections more friendly. (Feel free to discuss here or in gitter.)