Click here to Skip to main content
15,904,416 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
In my view say I have a ListView. In each ListItem there is an expander. Outside the ListView there is a button, to click it will expand or collapse all expanders.

Now I use Prism and MVVM in my WPF user control. What I did was in each expander I set a bool property which is binding with IsExpanded property. Then using ICommand in my ViewModel to control the properties as True or False.

My question is that is it again MVVM priciple? Should I do it in code behind instead of in ViewModel because the expanders are controls instead of data related?

What I have tried:

I had a disscussion with somebody. He said that I should do it in another way. Maybe he indicated in code behind to find all expanders like c# - How to programatically expand all expanders in window - Stack Overflow[^]
Posted
Updated 2-Apr-18 7:23am

I would create a behavior. The following is an example of a behavior:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Media;

namespace Medtronic.NIM4.UI.Common.Converters
{
    public class ResetRadioButtonOnVisibilityBehavior
    {
        public static bool GetEnable(DependencyObject obj)
        {
            return (bool)obj.GetValue(EnableProperty);
        }

        public static void SetEnable(DependencyObject obj, bool value)
        {
            obj.SetValue(EnableProperty, value);
        }

        public static readonly DependencyProperty EnableProperty =
            DependencyProperty.RegisterAttached("Enable",
                typeof(bool), typeof(ResetRadioButtonOnVisibilityBehavior),
                new UIPropertyMetadata(OnEnablePropertyChanged));

        private static void OnEnablePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var element = (FrameworkElement) d;
            if ((bool)e.NewValue)
                element.IsVisibleChanged += ElementOnIsVisibleChanged;
            else
                element.IsVisibleChanged -= ElementOnIsVisibleChanged;
         }

        private static void ElementOnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            var dependencyObject = (UIElement)sender;

            if (!(bool) dependencyPropertyChangedEventArgs.NewValue)
            {
                var checkBoxes = FindVisualChildren<ToggleButton>(dependencyObject).ToList();
                checkBoxes.ForEach(i => i.IsChecked = false);
            }
        }

        #region private static
        private static IEnumerable<T> FindVisualChildren<T>(DependencyObject root) where T : DependencyObject
        {
            if (root != null)
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(root); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(root, i);
                    if (child is T) yield return (T)child;
                    foreach (T childOfChild in FindVisualChildren<T>(child))
                        yield return childOfChild;
                }
        }
        #endregion
    }
}

Here is how you would use this behavior:
<Border converters:ResetRadioButtonOnVisibilityBehavior.Enable="True"
        Style="{StaticResource SettingsSideBorder}">
 
Share this answer
 
Comments
Member 12658724 1-Apr-18 17:20pm    
Thanks for your nice help. The question is that I want to toggle the button, switch between expand and collapse. Can the code achieve it?
Clifford Nelson 1-Apr-18 20:23pm    
What you do is make the DependencyProperty of type bool and Bind the DependencyProperty to the IsChecked value of the ToggleButton.
I use another way. Bind IsExpanded and IsChecked. Similar the method at c# - StackPanel Collapsed and Visible on Button Click - Stack Overflow[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900