【问题标题】:Labeled ComboBox in Windows 10 Universal AppWindows 10 通用应用程序中的标签组合框
【发布时间】:2015-09-11 10:28:25
【问题描述】:

类似于我的Labeled TextBox,其中的问题解决了:

Labeled TextBox in Windows Universal App

我的标签组合框中有两个问题,但首先是代码:

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. 如您所见,我尝试预选第一个项目,但不起作用,我不知道如何正确操作

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

【问题讨论】:

    标签: c# wpf xaml custom-controls win-universal-app


    【解决方案1】:

    建议您使用内置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 事件。

    【讨论】:

    • 非常感谢,非常适合我!感谢您对 Xaml 的建议,我不知道这样的事情是可能的,我会记住的,但是对于动态添加,我完成了 C#-Code!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-09
    • 2015-11-04
    • 2015-11-30
    相关资源
    最近更新 更多