如何根据另一个选择填充组合框?

时间:2012-11-16 12:48:46

标签: c# wpf combobox

我打开一个显示两个组合框的模态对话框。第一个按代码填充列表。当用户选择条目时,第二个组合框需要更改其基础列表。例如:第一个框显示连接到计算机的所有网络摄像头,第二个框显示所选网络摄像头的可用分辨率/流媒体功能。

这个是用System.Windows.Forms完成的,但是在Wpf和XAML中最好的方法是什么?

enter image description here

2 个答案:

答案 0 :(得分:1)

将第一个组合框的ItemsSource绑定到可用摄像机列表。对象应具有可用分辨率的属性。将SelectedItem绑定到视图模型的属性。然后,您可以将第二个组合框的ItemsSource属性绑定到SelectedCamera.AvailableResolutions或类似。

答案 1 :(得分:0)

这是一个完整的代码示例供其他人学习。首先是XAML,然后是代码隐藏。

<Window x:Class="CameraSelection.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:MyNamespace="clr-namespace:CameraSelection"
        Title="MainWindow" Height="350" Width="525">    
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>        
        <TextBlock Grid.Row="0" Grid.Column="0" HorizontalAlignment="Right" VerticalAlignment="Center">Camera</TextBlock>
        <!-- 
        bind the source to MainWindow.Cameras; 
        set value onto MainWindow.Camera; 
        set the display member;
        auto-select first entry 
        -->
        <ComboBox Name="comboCameras" Grid.Row="0" Grid.Column="1" Margin="5" 
                  SelectedItem="{Binding Path=Camera, RelativeSource={RelativeSource AncestorType=MyNamespace:MainWindow}}" 
                  ItemsSource="{Binding Path=Cameras, RelativeSource={RelativeSource AncestorType=MyNamespace:MainWindow}}"
                  DisplayMemberPath="Name" 
                  SelectedIndex="0"
                  />
        <TextBlock Grid.Row="1" Grid.Column="0" HorizontalAlignment="Right" VerticalAlignment="Center">Resolution</TextBlock>
        <!-- 
        bind the source to MainWindow.Resolutions; 
        set value onto MainWindow.Resolution;
        auto-select first entry;
        reload data according to MainWindow.PropertyChanged
        -->
        <ComboBox Name="comboResolutions" Grid.Row="1" Grid.Column="1" Margin="5" 
                  SelectedItem="{Binding Path=Resolution, RelativeSource={RelativeSource AncestorType=MyNamespace:MainWindow}}" 
                  ItemsSource="{Binding Path=Resolutions, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType=MyNamespace:MainWindow}}" 
                  SelectedIndex="0"
                  />
    </Grid>
</Window>

public partial class MainWindow : Window, INotifyPropertyChanged
{
    Camera camera;

    #region Setters for SelectedItem

    public Camera Camera 
    {
        get { return camera; }
        set
        {
            if (value == camera)
                return;

            camera = value;
            OnPropertyChanged("Camera");            // camera has changed
            OnPropertyChanged("Resolutions");       // available resolution might have changed too
        }
    }

    public Size Resolution
    {
        get;
        set;
    }

    #endregion

    #region ItemSources

    public IEnumerable<Camera> Cameras
    {
        get
        {
            yield return new Camera { Name = "Integrated Webcam", Resolutions = new[] { new Size(800,600), new Size(640,480) } };
            yield return new Camera { Name = "USB Webcam", Resolutions = new[] { new Size(1024, 768), new Size(800, 600) } };
        }
    }

    public IEnumerable<Size> Resolutions
    {
        get
        {
            if (Camera == null)
                yield break;

            foreach (Size resolution in camera.Resolutions)
                yield return resolution;
        }
    }

    #endregion

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion

    public MainWindow()
    {
        InitializeComponent();
    }
}

public class Camera
{
    public string Name { get; set; }

    public IEnumerable<Size> Resolutions 
    {
        get; set;
    }
}