简体   繁体   中英

WPF code to turn visibility off:on of multiple stackpanels

I have multiple stackpanels that are collapsed at first and as a button is clicked the stackpanel relating to the button click becomes visible. As off right now this is what I have that works.

private void Button1_Click(object sender, RoutedEventArgs e)
    {
        dgrid.ItemsSource = FillDataGrid("ShipWorksConnection", "GetPicklistItems", "PickList"); 

        SP1.Visibility = Visibility.Visible;            
        SP2.Visibility = Visibility.Collapsed;
        SP3.Visibility = Visibility.Collapsed;
        SP4.Visibility = Visibility.Collapsed;

    }
private void Button2_Click(object sender, RoutedEventArgs e)
    {
        dgrid.ItemsSource = FillDataGrid("SupplyConnection", "GetAllSupplies", "Supplies"); 

        SP1.Visibility = Visibility.Collapsed;
        SP2.Visibility = Visibility.Visible;
        SP3.Visibility = Visibility.Collapsed;
        SP4.Visibility = Visibility.Collapsed;

    }

and so on for multiple button click events. Is this the way to handle this and since I'll be adding more button click events is there something else I could do to make the code more reusable.

If there is some combined logic in the hiding / showing of elements, you can use a binding to toggle the visibility.

For this sample, you have to create a viewmodel and create a property TheConditionProperty in it. Then bind the view model to the control. In your scenario, you can even bind to an array of items, which will make it easier than adding properties over and over again.

<StackPanel>
    <StackPanel.Style>
        <Style TargetType="StackPanel">
            <Style.Triggers>
                <DataTrigger Binding="{Binding TheConditionProperty}" Value="False">
                    <Setter Property="Visibility" Value="Collapsed" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </StackPanel.Style>
</StackPanel>

WPF developers generally don't set the Visibility property of controls in procedural code like are doing. Instead, it is much more common to declare a bool property for each control that you want to show or hide and to use a BooleanToVisibilityConverter to convert your bool value to a Visibility value:

<SomeControl Visibility={Binding IsSomeControlVisible, 
    Converter={StaticResource BooleanToVisibilityConverter}} ... />

Then to show this control, you just set your IsSomeControlVisible property to true and to hide it, you set it to false .

add Simple  button click(Button_Click) to all the button (e.g button1 , button2)... In below code assume that u had button name property  as button1 and button2.



    private void Button_Click(object sender, RoutedEventArgs e)
            {
                Button b = sender as Button;
                List<StackPanel> CollapsedStackPanel = new List<StackPanel>();
                if (b.Name == Button1.Name)
                {
                    dgrid.ItemsSource = FillDataGrid("ShipWorksConnection", "GetPicklistItems", "PickList");
                    CollapsedStackPanel.Add(SP2);    //add only stackpanel that u want set Collapsed
                    CollapsedStackPanel.Add(SP3);    //add only stackpanel that u want set Collapsed
                    CollapsedStackPanel.Add(SP);    //add only stackpanel that u want set Collapsed
                }
                else if (b.Name == Button2.Name)
                {
                    dgrid.ItemsSource = FillDataGrid("ShipWorksConnection", "GetPicklistItems", "PickList");
                    CollapsedStackPanel.Add(SP1);    
                    CollapsedStackPanel.Add(SP3);    //add only stackpanel that u want set Collapsed
                    CollapsedStackPanel.Add(SP4);    //add only stackpanel that u want set Collapsed
                }
    //can add here more else if other buttons as well
                SetStackPanelVisibility(CollapsedStackPanel);
            }

            private void SetStackPanelVisibility(List<StackPanel> CollapsedStackPanel)
            {
                //get all the stackpanel in current window 
                //if its in visible list then set its visiblity to visible
                // else set its visibility to collapsed
                foreach (StackPanel item in FindVisualChildren<StackPanel>(this))
                {
                    if (CollapsedStackPanel.Contains(item))
                    {
                        item.Visibility = System.Windows.Visibility.Collpsed;
                    }
                }
            }


            public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
            {
                //preferably put this code in some common place so u can use whenever u want.
                if (depObj != null)
                {
                    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
                    {
                        DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                        if (child != null && child is T)
                        {
                            yield return (T)child;
                        }

                        foreach (T childOfChild in FindVisualChildren<T>(child))
                        {
                            yield return childOfChild;
                        }
                    }
                }
            }

Well, if there is no combined logic, then you could at least to "shortcut" it, just an idea, which you could workaround to be strongly typed.

ViewHelper.SetBulkVisibility(Visibility.Collapsed, new List<dynamic> {SP1, SP2, SP3});

 public static class ViewHelper
    {
        public static void SetBulkVisibility(Visibility value, IEnumerable<dynamic> objects)
        {
            foreach (var o in objects)
            {
                o.Visibility = value;
            }
        }
    }

Or

Maybe similiar method where to inverse current Visibility for objects in list.

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