Search code examples
wpfxamlmvvmmenudatatemplate

How to change the menu content by using DataTrigger in XAML?


I have two kinds of menu items according to the login. So, by using the property in the ViewModel Class

bool IsAdmin {get; set;}

I have to change the menu item content.I am not familiar with data template. I want to define all the menu items in the xaml itself (might be using the data templates). How we can bind the differnt menu items by using the data trigger. Can anyone can give a smaller example for this. using only this property and no c# codes.


Solution

  • Use ContentControl and Styles for max flexability in changing the view betwin Admin or not Admin views

    <UserControl.Resources>
        <!--*********** Control templates ***********-->
        <ControlTemplate x:Key="ViewA">
            <Views:AView/>
        </ControlTemplate>
        <ControlTemplate x:Key="ViewB">
            <Views:BView />
        </ControlTemplate>
    </UserControl.Resources>
    
    <Grid>
        <ContentControl DataContext="{Binding}" Grid.Row="1">
            <ContentControl.Style>
                <Style TargetType="ContentControl">
                    <Setter Property="Template" Value="{StaticResource ViewA}" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=IsAdmin}" Value="True">
                            <Setter Property="Template" Value="{StaticResource ViewB}" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl >
    </Grid>  
    

    Please keep in mind that you will have to implement the INPC interface on your VM in order to be able to change the state (is admin or not) on the fly.If not the change will be accepted only once(on the creation of the class that is holding the IsAdmin property). Here is the INPC implementation example:

    public class UserControlDataContext:BaseObservableObject
    {
    
        private bool _isAdmin;
    
        public bool IsAdmin
        {
            get { return _isAdmin; }
            set
            {
                _isAdmin = value;
                OnPropertyChanged();
            }
        }
    }
    
    /// <summary>
    /// implements the INotifyPropertyChanged (.net 4.5)
    /// </summary>
    public class BaseObservableObject : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    
        protected virtual void OnPropertyChanged<T>(Expression<Func<T>> raiser)
        {
            var propName = ((MemberExpression)raiser.Body).Member.Name;
            OnPropertyChanged(propName);
        }
    
        protected bool Set<T>(ref T field, T value, [CallerMemberName] string name = null)
        {
            if (!EqualityComparer<T>.Default.Equals(field, value))
            {
                field = value;
                OnPropertyChanged(name);
                return true;
            }
            return false;
        }
    }