动态更改WPF下拉列表的内容

时间:2015-11-24 08:39:33

标签: c# wpf

所以我有这两个应该有链接行为的下拉框。 例如:更改第一个下拉列表的内容时,第二个下拉列表的内容应该动态更改。

<ComboBox x:Name="ServerCombo"
          Loaded="Servers_ComboBox_Loaded"
          DropDownClosed="Servers_ComboBox_DropDownClosed"
          SelectionChanged="ServerCombo_SelectionChanged" />
<ComboBox x:Name="BuildCombo"
          SelectionChanged="Builds_ComboBox_SelectionChanged"
          Loaded="Builds_ComboBox_Loaded"
          DropDownClosed="Builds_ComboBox_DropDownClosed" />

因此,选择不同的服务器将触发BuildCombo框具有不同的值。 这是当前的代码(有点乱,对不起):

  public MainWindow()
    {
        InitializeComponent();
    }



    public void ScanBuilds(object sender, RoutedEventArgs e)
    {
        var dialog = new System.Windows.Forms.FolderBrowserDialog();
        hubBuildsList(hubPath);
    }

    public List<string> hubBuildsList(string hubPath)
    {
        string[] sDirectories = Directory.GetDirectories(hubPath);
        List<string> lDirectories = new List<string>();
        for (int i = 0; i < sDirectories.Length; i++)
        {
            string sDirectory = sDirectories[i];
            sDirectory = sDirectory.Substring(sDirectory.LastIndexOf(@"\")).Remove(0,1);
            lDirectories.Add(sDirectory);
        }
        return lDirectories;
    }

    public List<string> ServersList()
    {
        List<string> lServersList = new List<string>();
        lServersList.Add("qa02");
        lServersList.Add("qa03");
        lServersList.Add("qa04");
        return lServersList;
    }

    public void MoveBuild(string sSelectedBuild)
    {
        string a = sSelectedBuild;
        string sBuildToMove = hubPath + "\\" +  sSelectedBuild;
        string sDestinationPath = hubInstallationPath + "\\" + sSelectedBuild;
        Directory.CreateDirectory(sDestinationPath);
        DirectoryCopy(sBuildToMove, sDestinationPath);

    }

    private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs = true)
    {
        // Get the subdirectories for the specified directory.
        DirectoryInfo dir = new DirectoryInfo(sourceDirName);

        if (!dir.Exists)
        {
            throw new DirectoryNotFoundException(
                "Source directory does not exist or could not be found: "
                + sourceDirName);
        }

        DirectoryInfo[] dirs = dir.GetDirectories();
        // If the destination directory doesn't exist, create it.
        if (!Directory.Exists(destDirName))
        {
            Directory.CreateDirectory(destDirName);
        }

        // Get the files in the directory and copy them to the new location.
        FileInfo[] files = dir.GetFiles();
        foreach (FileInfo file in files)
        {
            string temppath = System.IO.Path.Combine(destDirName, file.Name);
            file.CopyTo(temppath, false);
        }

        // If copying subdirectories, copy them and their contents to new location.
        if (copySubDirs)
        {
            foreach (DirectoryInfo subdir in dirs)
            {
                string temppath = System.IO.Path.Combine(destDirName, subdir.Name);
                DirectoryCopy(subdir.FullName, temppath, copySubDirs);
            }
        }
    }

    private void hub_ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {

    }

    private void hubCombo_DropDownClosed(object sender, EventArgs e)
    {
        sSelectedhub = (string)(hubCombo.SelectedItem);
    }

    private void hub_ComboBox_Loaded(object sender, RoutedEventArgs e)
    {
        List<string> data = hubBuildsList(hubPath);
        var comboBox = sender as ComboBox;
        comboBox.ItemsSource = data;
        comboBox.SelectedIndex = 0;
    }


    private void Servers_ComboBox_DropDownClosed(object sender, EventArgs e)
    {

    }

    private void Install_Button_Click(object sender, RoutedEventArgs e)
    {
        MoveBuild(sSelectedhub);

    }

    private void Servers_ComboBox_Loaded(object sender, RoutedEventArgs e)
    {
        List<string> data = ServersList();
        var comboBox = sender as ComboBox;
        comboBox.ItemsSource = data;
        comboBox.SelectedIndex = 0;
    }

    private void Builds_ComboBox_DropDownClosed(object sender, EventArgs e)
    {
        sSelectedServer = (string)(ServerCombo.SelectedItem);
        List<string> data = BuildsList(sSelectedServer);
        //List<string> data = ServersList();
        var comboBox = sender as ComboBox;
        comboBox.ItemsSource = data;
        comboBox.SelectedIndex = 0;
        //BuildCombo.SelectedIndex = BuildCombo.FindStringExact("test1");
        //BuildCombo.text = "test1";
    }

    private List<string> BuildsList(string sServer)
    {
        string[] sDirectories = Directory.GetDirectories(sServer);
        List<string> lBuildsList = new List<string>();

        for (int i = 0; i < sDirectories.Length; i++)
        {
            string sDirectory = sDirectories[i];
            sDirectory = sDirectory.Substring(sDirectory.LastIndexOf(@"\")).Remove(0, 1);
            lBuildsList.Add(sDirectory);
        }

        lBuildsList.Add("qa02");
        return lBuildsList;
    }

    private void Builds_ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {

    }

    private void Builds_ComboBox_Loaded(object sender, RoutedEventArgs e)
    {
        sSelectedServer = (string)(ServerCombo.SelectedItem);
        List<string> data = BuildsList(sSelectedServer);
        var comboBox = sender as ComboBox;
        comboBox.ItemsSource = data;
        comboBox.SelectedIndex = 0;
    }

    private void ServerCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {

    }
}

}

谢谢!

2 个答案:

答案 0 :(得分:0)

SelectedServer是所选服务器的依赖项属性,SelectedBuild是基于SelectedServer的选定构建。 BuildsList是基于SelectedServer的构建列表。

为简单起见,SelectedServer和SelectedBuild是整数,但您可以轻松地将它们转换为任何viewmodel对象。

我还建议创建一个单独的viewmodel对象,其中包含SelectedServer,SelectedBuild,BuildsList和ServerList。通过这种方式,您可以重复使用代码。

MainWindow.cs:

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public static readonly DependencyProperty SelectedServerProperty =
         DependencyProperty.Register("SelectedServer", typeof(int),
         typeof(MainWindow), new FrameworkPropertyMetadata(0, SelectedIndexPropertyChangedCallback));

    public static readonly DependencyProperty SelectedBuildProperty =
         DependencyProperty.Register("SelectedBuild", typeof(int),
         typeof(MainWindow), new FrameworkPropertyMetadata(0));

    public static readonly DependencyProperty BuildsListProperty =
         DependencyProperty.Register("BuildsList", typeof(object),
         typeof(MainWindow), new FrameworkPropertyMetadata(null));

    public int SelectedServer
    {
        get { return (int)GetValue(SelectedServerProperty); }
        set { SetValue(SelectedServerProperty, value); }
    }

    public int SelectedBuild
    {
        get { return (int)GetValue(SelectedBuildProperty); }
        set { SetValue(SelectedBuildProperty, value); }
    }

    public object BuildsList
    {
        get { return GetValue(BuildsListProperty); }
        set { SetValue(BuildsListProperty, value); }
    }


    static void SelectedIndexPropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        var window = sender as MainWindow;
        window.GenerateBuilds();
    }

    void GenerateBuilds()
    {
        var selectedServer = SelectedServer + 1;
        BuildsList = new List<string>() {
            "Build 1." + selectedServer, "Build 2." + selectedServer, "Build 3." + selectedServer };
        SelectedBuild = 0;
    }

    public MainWindow()
    {
        InitializeComponent();
        LayoutRoot.DataContext = this;
        GenerateBuilds();
    }
}

MainWindow.xaml.cs:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApplication1"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid x:Name="LayoutRoot">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="Auto"></RowDefinition>
    </Grid.RowDefinitions>
    <ComboBox SelectedIndex="{Binding SelectedServer, Mode=TwoWay}">
        <ComboBoxItem Content="Server 1"></ComboBoxItem>
        <ComboBoxItem Content="Server 2"></ComboBoxItem>
        <ComboBoxItem Content="Server 3"></ComboBoxItem>
    </ComboBox>
    <ComboBox Grid.Row="1" ItemsSource="{Binding BuildsList}" SelectedIndex="{Binding SelectedBuild, Mode=TwoWay}" />
</Grid>
</Window>

答案 1 :(得分:0)

我认为你应该将你的组合框绑定到两个实现INotifyPropertyChanged的ObservableCollections

此外,提取文件夹名称很痛苦,请尝试:

new DirectoryInfo(path).Name;