Windows 10 通用应用程序中的标记组合框

Labeled ComboBox in Windows 10 Universal App

与我的 Labeled TextBox 类似,问题已解决:

我的 Labeled Combobox 有两个问题,但首先是代码:

Generic.xaml:

<Style TargetType="template:LabeledComboBox">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="template:LabeledComboBox">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <TextBlock Text="{TemplateBinding Label}" FontWeight="Bold" VerticalAlignment="Center" Margin="10,0" />
                    <ComboBox x:Name="PART_ComboBox" ItemsSource="{TemplateBinding ItemsSource}" SelectedIndex="{TemplateBinding SelectedIndex}" SelectedValue="{TemplateBinding SelectedValue}" SelectedValuePath="{TemplateBinding SelectedValuePath}" DisplayMemberPath="{TemplateBinding DisplayMemberPath}" VerticalAlignment="Center" Margin="20,0,10,0" Grid.Row="1" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

LabeledComboBox.cs:

[TemplatePart(Name = "PART_ComboBox", Type = typeof(ComboBox))]
public sealed class LabeledComboBox : Control, IParameterReturnable
{
    public static readonly DependencyProperty LabelProperty = DependencyProperty.Register("Label", typeof(string), typeof(LabeledComboBox), new PropertyMetadata(""));
    public string Label
    {
        get { return GetValue(LabelProperty).ToString(); }
        set { SetValue(LabelProperty, value); }
    }

    public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof(object), typeof(LabeledComboBox), new PropertyMetadata(null));
    public object ItemsSource
    {
        get { return GetValue(ItemsSourceProperty); }
        set { SetValue(ItemsSourceProperty, value); }
    }

    public static readonly DependencyProperty SelectedIndexProperty = DependencyProperty.Register("SelectedIndex", typeof(int), typeof(LabeledComboBox), new PropertyMetadata(default(int)));
    public int SelectedIndex
    {
        get { return (int) GetValue(SelectedIndexProperty); }
        set { SetValue(SelectedIndexProperty, value); }
    }

    public static readonly DependencyProperty SelectedValueProperty = DependencyProperty.Register("SelectedValue", typeof(object), typeof(LabeledComboBox), new PropertyMetadata(null));
    public object SelectedValue
    {
        get { return GetValue(SelectedValueProperty); }
        set { SetValue(SelectedValueProperty, value); }
    }

    public static readonly DependencyProperty SelectedValuePathProperty = DependencyProperty.Register("SelectedValuePath", typeof(string), typeof(LabeledComboBox), new PropertyMetadata(default(string)));
    public string SelectedValuePath
    {
        get { return GetValue(SelectedValuePathProperty).ToString(); }
        set { SetValue(SelectedValuePathProperty, value); }
    }

    public static readonly DependencyProperty DisplayMemberPathProperty = DependencyProperty.Register("DisplayMemberPath", typeof(string), typeof(LabeledComboBox), new PropertyMetadata(default(string)));
    public string DisplayMemberPath
    {
        get { return GetValue(DisplayMemberPathProperty).ToString(); }
        set { SetValue(DisplayMemberPathProperty, value); }
    }

    private ComboBox _comboBox;

    public LabeledComboBox()
    {
        this.DefaultStyleKey = typeof(LabeledComboBox);
    }

    public LabeledComboBox(List<Parameter> parameterList)
    {
        this.Label = parameterList[0].DisplayName ?? "";
        this.ItemsSource = parameterList;
        this.SelectedValuePath = "DefaultValue";
        this.DisplayMemberPath = "DefaultValue";
        this.SelectedIndex = 0;
        this.DefaultStyleKey = typeof(LabeledComboBox);
    }

    protected override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        _comboBox = GetTemplateChild("PART_ComboBox") as ComboBox;

        if (_comboBox != null)
        {
            _comboBox.SelectionChanged += OnComboBoxSelectionChanged;
            if (_comboBox.Items != null)
            {
                this.SelectedIndex = 0;
                _comboBox.SelectedValue = _comboBox.Items[this.SelectedIndex];
            }
        }
    }

    private void OnComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        this.SelectedValue = _comboBox.SelectedValue;
    }

    public string GetKey()
    {
        return Label;
    }

    public string GetValue()
    {
        return SelectedValue.ToString();
    }

}

它将以两种不同的方式被调用:

在 C# 中是动态的:

stackPanel.Add(new LabeledComboBox(parameterList));

静态 Xaml:

<templates:LabeledComboBox Label="Kategorien:" ItemsSource="{Binding ElementName=pageRoot, Path=FeedCategories}" DisplayMemberPath="Name" SelectedValuePath="Name" />

正如我之前所说,我遇到了两个问题:

  1. 如何绑定 SelectionChangedEvent 以在 Xaml 中访问它 || C#
  2. 如您所见,我尝试预选第一个项目,但它不起作用,我不知道如何正确选择

非常感谢您提前提供所有有用且善意的回答!

与其创建自定义控件并重新创建所有需要的依赖属性,我建议您使用内置 ComboBoxHeaderHeaderTemplate 属性,它们将被显示,就像在选择菜单上方的 LabeledComboBox 中一样。此外,SelectionChanged 活动将可用。

因此 XAML 中的用法如下所示:

    <ComboBox
        DisplayMemberPath="Name"
        Header="Kategorien:"
        ItemsSource="{Binding ElementName=pageRoot, Path=FeedCategories}"
        SelectedValuePath="Name"
        SelectionChanged="OnSelectionChanged">
        <ComboBox.HeaderTemplate>
            <DataTemplate>
                <TextBlock
                    Margin="10,0"
                    VerticalAlignment="Center"
                    FontWeight="Bold"
                    Text="{Binding}" />
            </DataTemplate>
        </ComboBox.HeaderTemplate>
    </ComboBox>

但是如果您不想使用上述方法,要在您的 LabeledComboBox 中公开选择更改事件,请添加以下代码:

    private void OnComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        this.SelectedValue = _comboBox.SelectedValue;
        this.RaiseSelectionChanged(e);
    }

    public event EventHandler<SelectionChangedEventArgs> SelectionChanged;

    private void RaiseSelectionChanged(SelectionChangedEventArgs args)
    {
        if (SelectionChanged != null)
        {
            SelectionChanged(this, args);
        }
    }

然后您可以使用从 XAML 创建的 SelectionChanged 事件。