我打开一个显示两个组合框的模式对话框。第一个由代码填充列表。当用户选择一个条目时,第二个组合框需要更改其基础列表。例如:第一个框显示连接到计算机的所有网络摄像头,第二个框显示所选网络摄像头的可用分辨率/流媒体功能。
这是使用 System.Windows.Forms 完成的,但是在 Wpf 和 XAML 中执行此操作的最佳方法是什么?
将第一个组合框的绑定ItemsSource
到可用摄像机列表。对象应具有可用分辨率的属性。绑定SelectedItem
到视图模型的属性。然后您可以将ItemsSource
第二个组合框的属性绑定到SelectedCamera.AvailableResolutions
或类似。
这里有一个完整的代码示例供其他人学习。首先是 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;
}
}