如何以编程方式将一组 ComboBoxItem 添加到 wpf 中的多个 ComboBox?
How to add one array of ComboBoxItem to multiple ComboBox in wpf programmatically?
我正在尝试将 ComboBoxItem 数组添加到多个 ComboBox,
但是选择一个ComboBox后,其他的会影响选择。
我的代码:
Dim arrColors() As ComboBoxItem = {
New ComboBoxItem With {.Content = "سفارشی", .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "آبی", .Background = TryFindResource("BrushPrimary"), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "سبز", .Background = TryFindResource("BrushSuccess"), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "زرد", .Background = TryFindResource("BrushWarning"), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "قرمز", .Background = TryFindResource("BrushDanger"), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "سفید", .Background = TryFindResource("BrushLight"), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "مشکی", .Background = TryFindResource("BrushDark"), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "طوسی", .Background = TryFindResource("FormBackground"), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "خاکستری", .Background = TryFindResource("SplitterColor"), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "صورتی", .Background = New SolidColorBrush(Colors.Pink), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "بنفش", .Background = New SolidColorBrush(Colors.Purple), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "قهوهای", .Background = New SolidColorBrush(Colors.Brown), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "نارنجی", .Background = New SolidColorBrush(Colors.Orange), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "آبی کمرنگ", .Background = New SolidColorBrush(Colors.LightBlue), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "سبز کمرنگ", .Background = New SolidColorBrush(Colors.LightGreen), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top}
}
尝试过的方法:
cmbThemeBack1.ItemsSource = New List(arrColors.Clone)
cmbTextColor1.ItemsSource = arrColors.Clone
但其中 none 是正确的。
UIElement
的每个实例只允许在 XAML 对象图中存在一次。这意味着您不能创建 UIElement
例如 ComboBoxItem
然后将其作为子元素添加到多个元素例如 ComboBox
.
选项 1
使用单独的 ComboBoxItem
个实例创建每个 ComboBox
:
<StackPanel>
<StackPanel.Resources>
<SolidColorBrush x:Key="BrushWarning" Color="Orange" />
</StackPanel.Resources>
<ComboBox x:Name="FirstComboBox">
<ComboBox.Items>
<ComboBoxItem Content="First Item" Background="{StaticResource BrushWarning}" />
<ComboBoxItem Content="Second Item" />
</ComboBox.Items>
</ComboBox>
<ComboBox x:Name="SecondComboBox">
<ComboBox.Items>
<ComboBoxItem Content="First Item" Background="{StaticResource BrushWarning}" />
<ComboBoxItem Content="Second Item" />
</ComboBox.Items>
</ComboBox>
</StackPanel>
我建议使用 XAML 而不是 C#,因为某些操作更方便,例如使用 StaticResource
标记的资源查找。
选项 2(推荐)
使用数据模型的共享源集合,让框架使用 DataTemplate
:
动态创建 ComboBoxItem
元素
ItemModel.cs
为了提高性能,建议 始终 让绑定源实现 INotifyPropertyChanged
(即使您根本不会引发 PropertyChanged
事件)。
Public Class ItemModel
Inherits INotifyPropertyChanged
Public Sub New()
Me.New(Brushes.Transparent)
End Sub
Public Sub New(ByVal background As Brush)
Me.Background = background
End Sub
Public Property Background As Brush
Public Property Text As String
Public Event PropertyChanged As PropertyChangedEventHandler
Protected Overridable Sub OnPropertyChanged(<CallerMemberName> ByVal Optional propertyName As String = Nothing)
Me.PropertyChanged?.Invoke(Me, New PropertyChangedEventArgs(propertyName))
End Sub
End Class
MainWindow.xaml.cs
为了获得最佳性能,将绑定源实现为 DependencyProperty
.
Partial Class MainWindow
Inherits Window
Public Shared ReadOnly ItemModelsProperty As DependencyProperty = DependencyProperty.Register(
"ItemModels",
GetType(ObservableCollection(Of ItemModel)),
GetType(MainWindow),
New PropertyMetadata(Nothing))
Public Property ItemModels As ObservableCollection(Of ItemModel)
Get
Return CType(GetValue(MainWindow.ItemModelsProperty), ObservableCollection(Of ItemModel))
End Get
Set(ByVal value As ObservableCollection(Of ItemModel))
Return SetValue(MainWindow.ItemModelsProperty, value)
End Set
End Property
Public Sub New()
Me.ItemModels = New ObservableCollection(Of ItemModel) From {
New ItemModel With {
.Text = "First Item",
.Background = Brushes.Yellow
},
New ItemModel With {
.Text = "Second Item",
.Background = Brushes.Blue
}
}
End Sub
End Class
MainWindow.xaml
<Window x:Name="Window">
<Window.Resources>
<Style x:Key="ComboBoxItemStyle" TargetType="ComboBoxItem">
<Setter Property="Background" Value="{Binding Background}" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
</Style>
<DataTemplate x:Key="ComboBoxItemTemplate" DataType="{x:Type ItemModel}">
<TextBlock Text="{Binding Text}"/>
</DataTemplate>
</Window.Resources>
<StackPanel>
<ComboBox x:Name="FirstComboBox"
ItemsSource="{Binding ElementName=Window, Path=ItemModels}"
ItemContainerStyle="{StaticResource ComboBoxItemStyle}"
ItemTemplate="{StaticResource ComboBoxItemTemplate}" />
<ComboBox x:Name="SecondComboBox"
ItemsSource="{Binding ElementName=Window, Path=ItemModels}"
ItemContainerStyle="{StaticResource ComboBoxItemStyle}"
ItemTemplate="{StaticResource ComboBoxItemTemplate}" />
</StackPanel>
</Window>
请注意,如果您不必单独为每一行着色,则只需创建一个 string
的集合并将其绑定到每个 ComboBox
。这样您就不需要定义 DataTemplate
,因为 ComboBox
(或通常的 ItemsControl
)会自动创建一个 TextBlock
来显示每个 string
。
我正在尝试将 ComboBoxItem 数组添加到多个 ComboBox, 但是选择一个ComboBox后,其他的会影响选择。
我的代码:
Dim arrColors() As ComboBoxItem = {
New ComboBoxItem With {.Content = "سفارشی", .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "آبی", .Background = TryFindResource("BrushPrimary"), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "سبز", .Background = TryFindResource("BrushSuccess"), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "زرد", .Background = TryFindResource("BrushWarning"), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "قرمز", .Background = TryFindResource("BrushDanger"), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "سفید", .Background = TryFindResource("BrushLight"), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "مشکی", .Background = TryFindResource("BrushDark"), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "طوسی", .Background = TryFindResource("FormBackground"), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "خاکستری", .Background = TryFindResource("SplitterColor"), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "صورتی", .Background = New SolidColorBrush(Colors.Pink), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "بنفش", .Background = New SolidColorBrush(Colors.Purple), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "قهوهای", .Background = New SolidColorBrush(Colors.Brown), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "نارنجی", .Background = New SolidColorBrush(Colors.Orange), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "آبی کمرنگ", .Background = New SolidColorBrush(Colors.LightBlue), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top},
New ComboBoxItem With {.Content = "سبز کمرنگ", .Background = New SolidColorBrush(Colors.LightGreen), .HorizontalContentAlignment = HorizontalAlignment.Left, .VerticalContentAlignment = VerticalAlignment.Top}
}
尝试过的方法:
cmbThemeBack1.ItemsSource = New List(arrColors.Clone)
cmbTextColor1.ItemsSource = arrColors.Clone
但其中 none 是正确的。
UIElement
的每个实例只允许在 XAML 对象图中存在一次。这意味着您不能创建 UIElement
例如 ComboBoxItem
然后将其作为子元素添加到多个元素例如 ComboBox
.
选项 1
使用单独的 ComboBoxItem
个实例创建每个 ComboBox
:
<StackPanel>
<StackPanel.Resources>
<SolidColorBrush x:Key="BrushWarning" Color="Orange" />
</StackPanel.Resources>
<ComboBox x:Name="FirstComboBox">
<ComboBox.Items>
<ComboBoxItem Content="First Item" Background="{StaticResource BrushWarning}" />
<ComboBoxItem Content="Second Item" />
</ComboBox.Items>
</ComboBox>
<ComboBox x:Name="SecondComboBox">
<ComboBox.Items>
<ComboBoxItem Content="First Item" Background="{StaticResource BrushWarning}" />
<ComboBoxItem Content="Second Item" />
</ComboBox.Items>
</ComboBox>
</StackPanel>
我建议使用 XAML 而不是 C#,因为某些操作更方便,例如使用 StaticResource
标记的资源查找。
选项 2(推荐)
使用数据模型的共享源集合,让框架使用 DataTemplate
:
ComboBoxItem
元素
ItemModel.cs
为了提高性能,建议 始终 让绑定源实现 INotifyPropertyChanged
(即使您根本不会引发 PropertyChanged
事件)。
Public Class ItemModel
Inherits INotifyPropertyChanged
Public Sub New()
Me.New(Brushes.Transparent)
End Sub
Public Sub New(ByVal background As Brush)
Me.Background = background
End Sub
Public Property Background As Brush
Public Property Text As String
Public Event PropertyChanged As PropertyChangedEventHandler
Protected Overridable Sub OnPropertyChanged(<CallerMemberName> ByVal Optional propertyName As String = Nothing)
Me.PropertyChanged?.Invoke(Me, New PropertyChangedEventArgs(propertyName))
End Sub
End Class
MainWindow.xaml.cs
为了获得最佳性能,将绑定源实现为 DependencyProperty
.
Partial Class MainWindow
Inherits Window
Public Shared ReadOnly ItemModelsProperty As DependencyProperty = DependencyProperty.Register(
"ItemModels",
GetType(ObservableCollection(Of ItemModel)),
GetType(MainWindow),
New PropertyMetadata(Nothing))
Public Property ItemModels As ObservableCollection(Of ItemModel)
Get
Return CType(GetValue(MainWindow.ItemModelsProperty), ObservableCollection(Of ItemModel))
End Get
Set(ByVal value As ObservableCollection(Of ItemModel))
Return SetValue(MainWindow.ItemModelsProperty, value)
End Set
End Property
Public Sub New()
Me.ItemModels = New ObservableCollection(Of ItemModel) From {
New ItemModel With {
.Text = "First Item",
.Background = Brushes.Yellow
},
New ItemModel With {
.Text = "Second Item",
.Background = Brushes.Blue
}
}
End Sub
End Class
MainWindow.xaml
<Window x:Name="Window">
<Window.Resources>
<Style x:Key="ComboBoxItemStyle" TargetType="ComboBoxItem">
<Setter Property="Background" Value="{Binding Background}" />
<Setter Property="HorizontalContentAlignment" Value="Left" />
</Style>
<DataTemplate x:Key="ComboBoxItemTemplate" DataType="{x:Type ItemModel}">
<TextBlock Text="{Binding Text}"/>
</DataTemplate>
</Window.Resources>
<StackPanel>
<ComboBox x:Name="FirstComboBox"
ItemsSource="{Binding ElementName=Window, Path=ItemModels}"
ItemContainerStyle="{StaticResource ComboBoxItemStyle}"
ItemTemplate="{StaticResource ComboBoxItemTemplate}" />
<ComboBox x:Name="SecondComboBox"
ItemsSource="{Binding ElementName=Window, Path=ItemModels}"
ItemContainerStyle="{StaticResource ComboBoxItemStyle}"
ItemTemplate="{StaticResource ComboBoxItemTemplate}" />
</StackPanel>
</Window>
请注意,如果您不必单独为每一行着色,则只需创建一个 string
的集合并将其绑定到每个 ComboBox
。这样您就不需要定义 DataTemplate
,因为 ComboBox
(或通常的 ItemsControl
)会自动创建一个 TextBlock
来显示每个 string
。