Mahapps.metro: Can't run MahApps 1.5.0 Caliburn Demos on VS2015

Created on 3 May 2017  路  17Comments  路  Source: MahApps/MahApps.Metro

Hello,

I can't run Caliburn demo projects (4.0 and 4.5) from my VS2015 workstation.
Both fails on AppBootstrapper GetInstance method , finding no contract for settings

image

Environment

  • MahApps.Metro 1.5.0
  • Windows 10
  • Visual Studio 2015
  • .NET Framework 4.0 && 4.5
Bug help wanted jump in

Most helpful comment

So I was able to recreate the problem outside of Caliburn.Micro with the following.

<ma:MetroWindow.Resources>
    <Style x:Key="CustomFlyoutStyle"
       BasedOn="{StaticResource {x:Type ma:Flyout}}"
       TargetType="{x:Type ma:Flyout}">
        <Setter Property="Header" Value="{Binding Title}" />
    </Style>
</ma:MetroWindow.Resources>

<ma:MetroWindow.Flyouts>
    <ma:FlyoutsControl x:Name="MyFlyouts" ItemContainerStyle="{StaticResource CustomFlyoutStyle}">
        <ma:FlyoutsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Item Template" />
                    <TextBlock Text="{Binding}" />
                </StackPanel>
            </DataTemplate>
        </ma:FlyoutsControl.ItemTemplate>
    </ma:FlyoutsControl>
</ma:MetroWindow.Flyouts>

<StackPanel>
    <Button x:Name="OpenFlyout" Content="Open" />
</StackPanel>
public class FlyoutViewModel
{
    public FlyoutViewModel(string title, string content)
    {
        Title = title;
        Content = content;
    }

    public string Title { get; }
    public string Content { get; }
}

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();

        Loaded += (s, e) =>
        {
            MyFlyouts.ItemsSource = Enumerable.Range(0, 10).Select(i => new FlyoutViewModel($"Title {i}", "Content for the flyout"));
        };

        OpenFlyout.Click += (s, e) =>
        {
            var flyout = MyFlyouts.ItemContainerGenerator.ContainerFromIndex(0) as Flyout;

            if (flyout == null)
                return;

            flyout.IsOpen = !flyout.IsOpen;
        };
    }
}

Which results in the following:

flyout

As you an see the ItemTemplate of the FlyoutsControl is being applied to the HeaderTemplate of the child Flyouts. Can't see anything immediately obvious in the code about why this is though.

All 17 comments

@oschwab Saw this too after 1.5.0 release, but I'm not a good Caliburn user

@punker76 I had an issue on my own project with flyouts after mahapps update ; as I used Caliburn sample as a basis, I tried to see how it was done in it, and boom !

Looks like caliburn can't locate views for the flyout viewmodels. I got the project to run by commenting out all fly-outs inside OnInitialize() function. Kind of defeats the purpose, since fly-outs are all there is to the demo. I will look into actually fixing the problem when I get some spare time.

image

I think it might be linked to this change :

_Change Flyout from ContentControl to HeaderedContentControl which has the correct properties for headers._

https://github.com/MahApps/MahApps.Metro/commit/2874108dd9df3cc5f3198f09d1681a135554200b

There's a related stackoverflow question, with no answers so far: http://stackoverflow.com/questions/43735278/wpf-mahapps-metro-caliburn-micro-flyout-headeredcontentcontrol

I've gotten the flyouts to work by commenting out 'this.Header = "' inside each Flyout constructor:

image

Obviously, that still doesn't help with locating and binding to their views, as you just end up with this:

image

@Eternal21 We're both exactly at the same point ...

@Eternal21 @punker76 Commenting the Binding to Header in ShellView.xaml makes the demo work again
image

Yes it does. The only problem now is, it displays the path to viewmodel now instead of the header title:

image

There's a related stackoverflow question, with no answers so far

Hey guys, it's me.

unbenannt

This works, but only if 1 Flyout is opened. If you're going to open another one, only the Header of the old one will be visible.

It seems it is a generally problem of Caliburn and HeaderedContentControl and/or the sample must be rewritten to work correctly.

@seb30 , your suggestion (setting the content) finally brought the agony of many hours to an end but as you mentioned the second one has problems. It shows only the header.

The one that shows the content is usually the first flyout added in viewmodel. I'm referring to my development project in VS2017. Did you have any success in resolving this situation? I chose to use CM only because I could not open/close flyout from viewmodel.

Thanks

Not really. In the end I'm showing only one Flyout and the other stuff in a dialog.

@seb30 Thank you for the reply. I have dropped the idea of using CM and going the normal way. Just to clarify to others on previous message, only the last added flyout shows the content and previous flyouts (1 or more) ones the header.
Cheers

I've dropped a work around in Caliburn-Micro/Caliburn.Micro#451 for the sample along with an explanation of what's happening.

Short story is that it appears that the ItemTemplate on the FlyoutsControl ends up as the HeaderTemplate of the Flyout. My gut says this part isn't related to Caliburn.Micro, but I need to spike a sample to test that out.

@nigel-sampson Thanks Nigel. Your workout seems to fix it. Cheers

So I was able to recreate the problem outside of Caliburn.Micro with the following.

<ma:MetroWindow.Resources>
    <Style x:Key="CustomFlyoutStyle"
       BasedOn="{StaticResource {x:Type ma:Flyout}}"
       TargetType="{x:Type ma:Flyout}">
        <Setter Property="Header" Value="{Binding Title}" />
    </Style>
</ma:MetroWindow.Resources>

<ma:MetroWindow.Flyouts>
    <ma:FlyoutsControl x:Name="MyFlyouts" ItemContainerStyle="{StaticResource CustomFlyoutStyle}">
        <ma:FlyoutsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Item Template" />
                    <TextBlock Text="{Binding}" />
                </StackPanel>
            </DataTemplate>
        </ma:FlyoutsControl.ItemTemplate>
    </ma:FlyoutsControl>
</ma:MetroWindow.Flyouts>

<StackPanel>
    <Button x:Name="OpenFlyout" Content="Open" />
</StackPanel>
public class FlyoutViewModel
{
    public FlyoutViewModel(string title, string content)
    {
        Title = title;
        Content = content;
    }

    public string Title { get; }
    public string Content { get; }
}

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();

        Loaded += (s, e) =>
        {
            MyFlyouts.ItemsSource = Enumerable.Range(0, 10).Select(i => new FlyoutViewModel($"Title {i}", "Content for the flyout"));
        };

        OpenFlyout.Click += (s, e) =>
        {
            var flyout = MyFlyouts.ItemContainerGenerator.ContainerFromIndex(0) as Flyout;

            if (flyout == null)
                return;

            flyout.IsOpen = !flyout.IsOpen;
        };
    }
}

Which results in the following:

flyout

As you an see the ItemTemplate of the FlyoutsControl is being applied to the HeaderTemplate of the child Flyouts. Can't see anything immediately obvious in the code about why this is though.

Was this page helpful?
0 / 5 - 0 ratings