简体   繁体   中英

Enable admin mode view in caliburn.micro

I am re-writing a WPF app to use Caliburn.Micro. The app is a menu system that shows Folders and then files within those folders. The problem is that I need to allow the user to switch to an "Admin" mode which will allow additional options. I currently have a FolderView and FileView along with ViewModels for each. I was thinking of having a seperate FolderAdminView and FileAdminView so I can change the UI and enable the additional options. The problem is switching between the two when the user changes modes.

Both a FolderViewModel and FileViewModel can be loaded at the same time so a call to DeactivateItem(ActiveItem, true); will act as a back button and return to the folder view.

I would also like to carry over values from the FolderViewModel to the FolderAdminViewModel since the main difference is UI.

Is there an easy way to swap out items in the WindowManager or an easier way to do this altogether? Could I have one ViewModel but two Views? Is there a way to have both templates in one view and select the correct one there?

Can you not just have an IsAdmin property on your ViewModel and bind the visibility of your admin only items to that using a BooleanToVisibilityConverter ?

ViewModel

public bool IsAdmin
{
    get
    {
        //What ever you do to work out if user is admin 
        //omitted any INotifyPropertyChanged gubbins
    }
}

Xaml

<StackPanel Visibility="{Binding IsAdmin,Converter={StaticResource BooleanToVisibiltyConverter}}"></StackPanel>

Converter

public sealed class BooleanToVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var flag = false;
            if (value is bool)
            {
                flag = (bool)value;
            }
            else if (value is bool?)
            {
                var nullable = (bool?)value;
                flag = nullable.GetValueOrDefault();
            }
            if (parameter != null)
            {
                if (bool.Parse((string)parameter))
                {
                    flag = !flag;
                }
            }
            return flag ? Visibility.Visible : Visibility.Collapsed;
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var back = ((value is Visibility) && (((Visibility)value) == Visibility.Visible));
            if (parameter != null)
            {
                if ((bool)parameter)
                {
                    back = !back;
                }
            }
            return back;
        }
    }

You can use the 'context' attached property to specify the context for any views which are loaded eg:

<ContentControl x:Name="SomeSubViewModel" cal:View.Context="SomeContext" />

CM uses ToString() on the context object to obtain a value it will use to build the typename during view resolution. This means you can have multiple views for the same viewmodel and therefore add additional functions when the user is in admin mode by binding the View.Context property

You could also create a binding for each item you want to hide on the viewmodel and use a converter to check if the user is logged in etc - obviously it depends on whether you want to duplicate the XAML in two views or have a single view with conditional logic to hide/show areas

Read up on the context property:

http://caliburnmicro.codeplex.com/wikipage?title=All%20About%20Conventions&referringTitle=Documentation

the link above has some examples (in the first few sections)

and here:

http://caliburnmicro.codeplex.com/wikipage?title=Screens%2c%20Conductors%20and%20Composition

in the Multiple Views over the Same ViewModel section

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM