组合框“;选择项目“;结合
本文关键字:结合 项目 选择 组合 | 更新日期: 2023-09-27 18:20:31
我正在处理一些ComboBoxes,它们需要一个"select"属性作为WPF(c#)中的首选项
目前,我已经命名了组合框,然后从数组字符串填充到后面的代码中。
<ComboBox Width="150" x:Name="cmbTitle" Margin="3" SelectedIndex="0" />
cmbTitle.Items.Add("Select");
foreach (var title in Constants.Title)
cmbTitle.Items.Add(title);
我的问题是,所选的索引将始终偏离字符串中索引的1。
在做了研究之后,我发现这是一种非常史前的填充组合框的方式(WinFrom背景)。在我看过的每个例子中,常量似乎都存储在枚举中,所以我想去掉多个字符串[]。
在WPF中提供"选择"选项的同时,将枚举绑定到组合框的最佳方式是什么?我今天已经看了六个选项,我不太确定还应该列出哪些其他代码示例。
这是一个悬而未决的问题,但我很困惑。
提前感谢,Oli
-
枚举的值可以从
Enum.GetValues()
中检索,与方法的绑定通常使用ObjectDataProvider
完成。以下是获取所有BindingMode
值的示例:<ObjectDataProvider x:Key="BindingModes" ObjectType="{x:Type sys:Enum}" MethodName="GetValues"> <ObjectDataProvider.MethodParameters> <x:Type TypeName="BindingMode" /> </ObjectDataProvider.MethodParameters> </ObjectDataProvider>
现在,我们可以绑定
ComboBox
:的ItemsSource
<ComboBox ItemsSource="{Binding Source={StaticResource BindingModes}}" />
-
我们的控件需要一个新的提示属性:
public class ExtendedComboBox : ComboBox { public static readonly DependencyProperty PromptProperty = DependencyProperty.Register("Prompt", typeof(string), typeof(ExtendedComboBox), new PropertyMetadata(string.Empty)); public string Prompt { get { return (string)GetValue(PromptTextProperty); } set { SetValue(PromptTextProperty, value); } } }
我们可以作弊一点,在我们的控件中放置一个带有提示的
TextBlock
,并在选择项目时隐藏它。为此,我们用包含TextBlock
的新控件重写控件的ControlTemplate
。我从那里修改了模板:<Style x:Key="PromptTextBlock" TargetType="{x:Type TextBlock}" > <Setter Property="Visibility" Value="Hidden" /> <Style.Triggers> <DataTrigger Binding="{Binding SelectedItem, RelativeSource={RelativeSource TemplatedParent}}" Value="{x:Null}"> <Setter Property="Visibility" Value="Visible" /> </DataTrigger> </Style.Triggers> </Style> <Style x:Key="PromptedComboBox" TargetType="{x:Type local:ExtendedComboBox}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:ExtendedComboBox}"> <Grid> <ToggleButton x:Name="DropDownToggle" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="-1" HorizontalContentAlignment="Right" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"> <Path x:Name="BtnArrow" Height="4" Width="8" Stretch="Uniform" Margin="0,0,4,0" Fill="Black" Data="F1 M 300,-190L 310,-190L 305,-183L 301,-190 Z " /> </ToggleButton> <ContentPresenter x:Name="ContentPresenter" Margin="6,2,25,2" Content="{TemplateBinding SelectionBoxItem}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"> </ContentPresenter> <TextBox x:Name="PART_EditableTextBox" Style="{x:Null}" Focusable="False" Background="{TemplateBinding Background}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="3,3,23,3" Visibility="Hidden" IsReadOnly="{TemplateBinding IsReadOnly}"/> <Popup x:Name="PART_Popup" IsOpen="{TemplateBinding IsDropDownOpen}"> <Border x:Name="PopupBorder" HorizontalAlignment="Stretch" Height="Auto" MinWidth="{TemplateBinding ActualWidth}" MaxHeight="{TemplateBinding MaxDropDownHeight}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="Black" Background="White" CornerRadius="3"> <ScrollViewer x:Name="ScrollViewer" BorderThickness="0" Padding="1"> <ItemsPresenter/> </ScrollViewer> </Border> </Popup> <TextBlock Margin="4,3,20,3" Text="{Binding PromptText, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource PromptTextBlock}"/> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>
-
结合起来,我们有:
<local:ExtendedComboBox Style="{StaticResource PromptedComboBox}" Prompt="Select an item" ItemsSource="{Binding Source={StaticResource BindingModes}}" />
我认为填充组合框的最佳方式是使用IDictionary。
例如,您的代码隐藏:
public YourEnum SelectedOption { get; set; }
public IDictionary<string, YourEnum> Options = new Dictionary<string, YourEnum?>();
Options.Add("Select", null);
Options.Add("Option 1", YourEnum.Option1);
...
Options.Add("Option N", YourEnum.OptionN);
您的xaml文件:
<ComboBox ItemsSource="{Binding Options, ...}" SelectedValue="{Binding SelectedOption, ...}" DisplayMemberPath="Key" SelectedValuePath="Value" />