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));
}
以下代码通过在 运行 时由后面的 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));
}