使用组合框中的数据填充项目源

时间:2014-08-12 08:01:59

标签: c# wpf combobox

我有两个组合框,第一个是活动的,第二个只有在选择第一个项目时才会被激活。它取决于第一个,将要选择的内容,它将为后面的代码构建第二个组合框的不同项目源。例如

情景1

  

我选择第一个内容为1的组合框和第二个组合框   将使用数据A,B,C,D填充项目来源

场景2

  

我选择第一个含有内容2的组合框和第二个组合框   将使用数据T,Z,E,D填充项目来源

我的XAML代码段

<UserControl x:Class="RestoreComputer.Views.ConfigView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition Height="60"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="1" Orientation="Horizontal" Margin="20,0,0,0" Height="50">
            <ComboBox Name="_server" ItemsSource="{Binding Path=Servers}" SelectedItem="{Binding Path=Server}" IsSynchronizedWithCurrentItem="True" Width="100" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Text="18"/>
            <Image Source="../Images/narrow.png" Margin="10,0,10,0"/>
            <ComboBox Name="_computer" IsSynchronizedWithCurrentItem="True" SelectedItem="{Binding Path=Computer}" Width="100" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Text="18">
                <ComboBox.Style>
                    <Style BasedOn="{StaticResource ComboBoxStyle}" TargetType="ComboBox">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding SelectedItem, ElementName=_server}" Value="{x:Null}">
                                <Setter Property="IsEnabled" Value="False"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </ComboBox.Style>
            </ComboBox>

        </StackPanel>
    </Grid>
</UserControl>

和viewmodel

public string Server
{
    get { return _server; }
    set
    {
        if (value != _server)
        {
            _server = value;
            RaisePropertyChanged(ref _server, value, () => Server);
            Computers = GetComputers();
        }
    }
}

public IEnumerable<string> GetComputers()
{
    string nas = ReadServerPath(Server);
    NetworkPath.MapNetworkDrive(nas, SettingsXml.User, SettingsXml.Password);
    var subFolders = new DirectoryInfo(nas);
    IEnumerable<string> folders = subFolders.GetDirectories().Select(e => e.Name).ToList();
    NetworkPath.DisconnectNetworkDrive();
    return folders;
}

public IEnumerable<string> Computers
{
    get { return _computers; }

    set
    {
        _computers = value;
        RaisePropertyChanged(ref _computers, value, () => Computers);
    }
}

如何获得上述的愿望?

更新了代码: XAML

<UserControl x:Class="RestoreComputer.Views.ConfigView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition Height="60"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="1" Orientation="Horizontal" Margin="20,0,0,0" Height="50">
            <ComboBox Name="_server" ItemsSource="{Binding Path=Servers}" SelectedItem="{Binding Path=Server}" Width="100" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Text="18"/>
            <Image Source="../Images/narrow.png" Margin="10,0,10,0"/>
            <ComboBox Name="_computer" SelectedItem="{Binding Path=Computer}" ItemsSource="{Binding Path=Computers}" Width="100" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Text="18">
                <ComboBox.Style>
                    <Style BasedOn="{StaticResource ComboBoxStyle}" TargetType="ComboBox">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding SelectedItem, ElementName=_server}" Value="{x:Null}">
                                <Setter Property="IsEnabled" Value="False"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </ComboBox.Style>
            </ComboBox>

        </StackPanel>
    </Grid>
</UserControl>

视图模型

public string Server
{
    get { return _server; }
    set
    {
        if (value != _server)
        {
            _server = value;
            RaisePropertyChanged(ref _server, value, () => Server);
            if (Computers == null)
            {
                Computers = new ObservableCollection<string>();
            }
            else
            {
                Computers.Clear();
            }

            Computers = GetComputers();
        }
    }
}


public ObservableCollection<string> GetComputers()
{
    string nas = ReadServerPath(Server);
    NetworkPath.MapNetworkDrive(nas, SettingsXml.User, SettingsXml.Password);
    var subFolders = new DirectoryInfo(nas);
    var folders = new ObservableCollection<string>();
    subFolders.GetDirectories().Select(e => e.Name).LookUp(folders.Add);
    NetworkPath.DisconnectNetworkDrive();
    return folders;
}

仍然无效。

更新3

我将代码更改为。

public string Server
    {
        get { return _server; }
        set
        {
            if (value != _server)
            {
                _server = value;
                RaisePropertyChanged(ref _server, value, () => Server);
                if (Computers == null)
                {
                    Computers = new ObservableCollection<string>();
                }
                else
                {
                    Computers.Clear();
                }

                foreach (var ele in GetComputers())
                {
                    Computers.Add(ele);
                }

            }
        }
    }

    public IEnumerable<string> GetComputers()
    {
        string nas = ReadServerPath(Server);
        NetworkPath.MapNetworkDrive(nas, SettingsXml.User, SettingsXml.Password);
        var subFolders = new DirectoryInfo(nas);
        NetworkPath.DisconnectNetworkDrive();
        foreach (var folder in subFolders.GetDirectories())
        {
            yield return folder.Name;
        }
    }

1 个答案:

答案 0 :(得分:1)

最简单的方法是,如果你像你一样为Combobox 1进行绑定。

如果选择了combo1中的项目,则使用正确的项目填充计算机集合。所以每次combo1 SelectedItem发生变化时,combo2的数据源都会发生变化。如果Combo没有选择任何项目,则combo2的数据源为空。

这有帮助吗?

public string Server
{
  get { return _server; }
  set
  {
      if (value != _server)
      {
          _server = value;
          RaisePropertyChanged(ref _server, value, () => Server);
          if(Computers == null) {
            Computers = new ObservableCollection<string>();
          } else {
            Computers.Clear();
          }
          Computers.AddRange(GetComputers());
      }
  }
}

您应该在ViewModel中为所有绑定列表使用ObservableCollection。

ObservableCollection

如果您使用ObservableCollection,那么如果集合发生更改,则会收到View通知。这就是你需要的。

工作示例

<强> XAML

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<StackPanel>
    <ComboBox ItemsSource="{Binding List1}" SelectedItem="{Binding SelectedList1}"></ComboBox>
    <ComboBox ItemsSource="{Binding List2}"></ComboBox>
</StackPanel>

代码背后

public partial class MainWindow : Window
{
  public MainWindow()
  {
    DataContext = this;
    List1 = new ObservableCollection<string> {"option1", "option2", "option3", "option4"};
    List2 = new ObservableCollection<string>();
    InitializeComponent();

  }

  private string m_selectedList1;
  public string SelectedList1
  {
    get { return m_selectedList1; }
    set
    {
      m_selectedList1 = value;
      if (m_selectedList1 == "option1")
      {
        List2.Clear();
        List2.Add("12345");
        List2.Add("123456");
      }
      if (m_selectedList1 == "option2")
      {
        List2.Clear();
        List2.Add("123");
        List2.Add("1234");
      }
    }
  }

  public ObservableCollection<string> List1 { get; set; }
  public ObservableCollection<string> List2 { get; set; }
}