简体   繁体   中英

Updating a ListBox with different Content On Button Clicks in WPF

So I have a listbox and a tool bar in my WPF app. The tool bar just has regular controls, and the listbox has vertical expanders.

I need the listbox to have a different set of expanders depending on what button is clicked. Right now it looks like such:

<ListBox>
    <local:Select_Analysis_Panel/>
</ListBox>

Where local:Select_Analysis_Panel is seperate user control file containing the expanders. What is the best way to go about dynamically updating the ListBox control's content upon a button click?

For the last couple hours I've been trying to use set DataTemplates for each expander set and bind the to the items control property with little avail with the code below. I'm just trying to get basic framework laid out before setting up a MVVM interface. Later on I was going to replace the ItemsSource="Network_anal" with you know ItemsSource="{Binding WhatExpanderViewModelProperty}" or something like that.

 <ListBox Width="250"  Margin="5,0,0,0">
            <ListBox.Resources>

                <DataTemplate DataType="Select_Analysis_Panel">
                    <local:Select_Analysis_Panel/>
                </DataTemplate>

                <DataTemplate x:Key="Network_anal" DataType="NetworkAnalysis">
                    <local:NetworkAnalysis/>
                </DataTemplate>.Resources>

            <ListBox.Template>                    
                <ControlTemplate>
                    <Border Background="Red"/>
                </ControlTemplate>                    
            </ListBox.Template>

            <ItemsControl ItemsSource="Network_anal"/>
</ListBox>

Am I taking the right approach to this at all?

Here's what I'm trying to do. Below when the "File" button is clicked the side bar displays these 2 expanders:

在此输入图像描述 And when "Network Design" button these expanders are dipslayed:

在此输入图像描述

Option 1:

Subclassing the sections:

each of these sections could be subclassed from a base section class and a specific DataTemplate could be used for each:

<Window x:Class="MiscSamples.MultiToolbar"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MiscSamples"
        Title="MultiToolbar" Height="300" Width="300">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
    </Window.Resources>
    <DockPanel>
        <ListBox ItemsSource="{Binding Sections}"
                 SelectedItem="{Binding SelectedSection}"
                 DisplayMemberPath="Name"
                 DockPanel.Dock="Top">
            <ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem">
                    <Setter Property="IsEnabled" Value="{Binding IsEnabled}"/>
                    <Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource BoolToVisibilityConverter}}"/>
                    <Setter Property="MinWidth" Value="80"/>
                    <Setter Property="MinHeight" Value="40"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="ListBoxItem">
                                <Border BorderBrush="Black" BorderThickness="1">
                                    <ToggleButton IsChecked="{Binding IsSelected, Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}">
                                        <ContentPresenter ContentSource="Content"/>
                                    </ToggleButton>
                                </Border>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListBox.ItemContainerStyle>
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
        </ListBox>

        <ScrollViewer Width="300" DockPanel.Dock="Left">
            <ContentPresenter Content="{Binding SelectedSection}">
                <ContentPresenter.Resources>
                    <DataTemplate DataType="{x:Type local:FileSection}">
                        <TextBlock Text="User Control For File Section"/>
                    </DataTemplate>
                    <DataTemplate DataType="{x:Type local:NetworkDesignSection}">
                        <TextBlock Text="User Control For Network Design"/>
                    </DataTemplate>
                    <DataTemplate DataType="{x:Type local:SelectAnalysisSection}">
                        <TextBlock Text="User Control For Select Analysis"/>
                    </DataTemplate>
                </ContentPresenter.Resources>
            </ContentPresenter>
        </ScrollViewer>

        <Grid Background="Gray">
            <TextBlock Text="Design Surface" TextAlignment="Center" VerticalAlignment="Center" FontWeight="Bold"/>
        </Grid>
    </DockPanel>
</Window>

Code Behind:

public partial class MultiToolbar : Window
    {
        public MultiToolbar()
        {
            InitializeComponent();

            var vm = new MainViewModel();
            vm.Sections.Add(new FileSection() {Name = "File"});
            vm.Sections.Add(new NetworkDesignSection() { Name = "Network Design" });
            vm.Sections.Add(new SelectAnalysisSection() { Name = "Select Analysis" });

            DataContext = vm;
        }
    }

Main ViewModel:

public class MainViewModel: PropertyChangedBase
    {
        private ObservableCollection<Section> _sections;
        public ObservableCollection<Section> Sections
        {
            get { return _sections ?? (_sections = new ObservableCollection<Section>()); }
        }

        private Section _selectedSection;
        public Section SelectedSection
        {
            get { return _selectedSection; }
            set
            {
                _selectedSection = value;
                OnPropertyChanged("SelectedSection");
            }
        }
    }

Sections:

public abstract class Section:PropertyChangedBase
    {
        public string Name { get; set; }

        private bool _isEnabled = true;
        public bool IsEnabled
        {
            get { return _isEnabled; }
            set
            {
                _isEnabled = value;
                OnPropertyChanged("IsEnabled");
            }
        }

        private bool _isVisible = true;
        public bool IsVisible
        {
            get { return _isVisible; }
            set
            {
                _isVisible = value;
                OnPropertyChanged("IsVisible");
            }
        }

        //Optionally
        //public string ImageSource {get;set;}
        //ImageSource = "/Resources/MySection.png";
    }

    public class FileSection: Section
    {
        ///... Custom logic specific to this Section
    }

    public class NetworkDesignSection:Section
    {
        ///... Custom logic specific to this Section
    }

    public class SelectAnalysisSection: Section
    {
        ///... Custom logic specific to File Section
    }

    //...etc etc etc

Result:

在此输入图像描述

Notice that I'm using ToggleButton s bound to the ListBoxItem.IsSelected property to simulate a TabControl -like behavior.

您可以设置整个表单的DataContext并绑定listboxItemsSource ,或者直接将listbox ItemsSource设置为某个集合。

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