C#:如何在 UserControl 中填充组合项

C#: How to populate combo items in UserControl

以下代码通过在 运行 时由后面的 C# 代码填充组合框来工作。 我想从 XAML 以声明方式填充用户控件组合,类似于填充描述标签的方式。 此代码仅供我个人使用,因此我不会使用复杂的 MVVM 模型。理想情况下,我想要一个将字符串数组从主 XAML 代码传递到用户控件的解决方案,因为我想知道如何做到这一点。 提前致谢:-)

        //Main Window.xaml
    <Window
    x:Class="WpfApp1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApp1"
    mc:Ignorable="d"
    Title="Car Details"
    SizeToContent="WidthAndHeight">
    
    <StackPanel>
        <local:myControl
            x:Name="myMake"
            myDescription="Make" />

        <local:myControl
            x:Name="myModel"
            myDescription="Model" />

        <local:myControl
            x:Name="myYear"
            myDescription="Year" />

    </StackPanel>
</Window>


    //MainWindow.xaml.cs

using System.Windows;
namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            //myMake is the name of a specific myControl
            //myOption is the name of the combo within myControl
            myMake.myOptions.ItemsSource = new string[] { "Ford", "Toyota" };
        }
    }
}


    //myControl.xaml

<UserControl
    x:Class="WpfApp1.myControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:WpfApp1"
    mc:Ignorable="d">
    <StackPanel>
        <Label
            Content="{Binding myDescription,FallbackValue=description}"
            />
            
        <ComboBox
            x:Name="myOptions"
            Width="120" />
    </StackPanel>
</UserControl>



    //myControl.xaml.cs

using System.Windows;
using System.Windows.Controls;

namespace WpfApp1
{
    public partial class myControl : UserControl
    {
        public myControl()
        {
            InitializeComponent();
            this.DataContext = this;
        }

        public string myDescription
        {
            get { return (string)GetValue(myDescriptionProperty); }
            set { SetValue(myDescriptionProperty, value); }
        }

public static readonly DependencyProperty myDescriptionProperty = DependencyProperty.Register("myDescription", typeof(string), typeof(myControl), new PropertyMetadata(null));
    }
}

您可以像这样在 xaml 中声明一个字符串数组:

<x:Array xmlns:s="clr-namespace:System;assembly=mscorlib" x:Key="myStringArray" Type="{x:Type s:String}">
        <s:String>Ford</s:String>
        <s:String>Toyota</s:String>
</x:Array>

来源:

所以你的观点变成:

<Window x:Class="WpfApp1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApp1"
    mc:Ignorable="d"
    Title="Car Details" SizeToContent="WidthAndHeight">
<Window.Resources>
    <!--Declaration of an array of string which is added to the ressources of the window-->
    <x:Array xmlns:s="clr-namespace:System;assembly=mscorlib" x:Key="myStringArray" Type="{x:Type s:String}">
        <s:String>Ford</s:String>
        <s:String>Toyota</s:String>
    </x:Array>
</Window.Resources>
<StackPanel>
    <!--We get the array from the ressource by calling "StaticResource" with the key of the element to obtain-->
    <local:myControl
        x:Name="myMake" myDescription="Make" ArrayItemsSource="{StaticResource myStringArray}" />
    
    <!--Do the same for the other usercontrol -->
    <local:myControl
        x:Name="myModel"
        myDescription="Model" />

    <local:myControl
        x:Name="myYear"
        myDescription="Year" />

</StackPanel>

在你的用户控件中,你不应该使用 this.DataContext = this; 因为这是不好的做法,因为它会阻止你的用户控件继承视图的数据上下文(我知道你不打算使用 MVVM 但我认为这应该其他读者仍需提及)。

所以因为datacontext不是控件,usercontrol的xaml中的绑定必须修改成这样:{Binding ElementName=myControlName, Path=theNameOfThePropertyIwantToBind}

我创建了一个新的依赖项 属性 来从视图中传递字符串数组,这样用户控件就变成了: Xaml:

 <UserControl x:Class="WpfApp1.myControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp1" x:Name="myControlName"
mc:Ignorable="d">
<StackPanel>
    <Label
        Content="{Binding ElementName=myControlName, Path=myDescription,FallbackValue=description}"
        />

    <ComboBox
        x:Name="myOptions" ItemsSource="{Binding ElementName=myControlName, Path=ArrayItemsSource}"
        Width="120" />
</StackPanel>

背后的代码:

public partial class myControl : UserControl
{
    public myControl()
    {
        InitializeComponent();
        //Bad practice
        //this.DataContext = this;
    }

    public string myDescription
    {
        get { return (string)GetValue(myDescriptionProperty); }
        set { SetValue(myDescriptionProperty, value); }
    }

    public string[] ArrayItemsSource
    {
        get { return (string[])GetValue(ArrayItemsSourceProperty); }
        set { SetValue(ArrayItemsSourceProperty, value); }
    }

    public static readonly DependencyProperty myDescriptionProperty = DependencyProperty.Register("myDescription", typeof(string), typeof(myControl), new PropertyMetadata(null));

    public static readonly DependencyProperty ArrayItemsSourceProperty = DependencyProperty.Register(nameof(ArrayItemsSource), typeof(string[]), typeof(myControl), new PropertyMetadata(null));
}