如何以编程方式将一个组合框项数组添加到 wpf 中的多个组合框?



我正在尝试将ComboBoxItem的数组添加到多个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

但这些都不对。

每个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

最新更新