Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make MA.M more MVVM-friendly #999

Closed
AzureKitsune opened this issue Feb 3, 2014 · 15 comments
Closed

Make MA.M more MVVM-friendly #999

AzureKitsune opened this issue Feb 3, 2014 · 15 comments

Comments

@AzureKitsune
Copy link
Member

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.)

@zeluisping
Copy link
Contributor

Off-Topic: issue number 999

@Gimly
Copy link
Contributor

Gimly commented Feb 4, 2014

Opening a Flyout is relatively complex in a MVVM scenario.
For the record, how I did it in my project:

  • Created a "IFlyoutViewModel" interface that defines things common for all Flyouts (mostly IsOpen)
  • Defined that the MainWindow had a IFlyoutViewModel property that could be set (My app only has a flyout on the left, but it can contain different "UserControls"
  • Used Caliburn.Micro's event aggregator to define an event "Show flyout" that would pass a class derived from IFlyoutViewModel, set it as the current flyout and show it.

Works very nicely but you have to know how to use Caliburn's event aggregator.

@robertstefan
Copy link

Way to complicated ... especially for one that just begins using/learning MVVM ... 😒

@remcoros
Copy link
Contributor

remcoros commented Feb 4, 2014

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>

@punker76 punker76 mentioned this issue Apr 24, 2014
33 tasks
@flagbug
Copy link
Member

flagbug commented Jun 4, 2014

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.

@punker76
Copy link
Member

punker76 commented Jun 4, 2014

@flagbug 👍

@QuantumDeveloper
Copy link
Contributor

@flagbug if WPF developers in MS also thought so, then we never see controls with binding support and other cool features.

@thoemmi
Copy link
Collaborator

thoemmi commented Jul 23, 2014

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?

@papuashu
Copy link

I guess, in order to combine the two worlds, the best would be to create a library MA.M + Caliburn.Micro

@dealproc
Copy link

dealproc commented Jan 7, 2015

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?

@thoemmi
Copy link
Collaborator

thoemmi commented Jan 7, 2015

I've started with my own (opiniated) MVVM library based on MahApps.Metro, see TinyLittleMvvm. It still lacks some documenation though.

@papuashu
Copy link

papuashu commented Jan 8, 2015

Meantime, I've discovered Caliburn.Metro which seems to be a good start in this direction (Caliburn.Micro + MA.M)

@dealproc
Copy link

dealproc commented Jan 8, 2015

link @papuashu ?

@keithrfung
Copy link

@dealproc Caliburn.Metro

@bhaidar
Copy link

bhaidar commented Dec 7, 2016

@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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests