Вопрос или проблема
Я связывал списки с комбинированным полем в прошлом, но кажется, что это по-другому внутри шаблона данных. У меня есть выбор в списке, который я хочу использовать для заполнения комбинированного поля, и у меня также есть значение, которое я передаю в комбинированное поле для выбора по умолчанию в зависимости от сценария. Я не могу разобраться, как связать список.
Это список, который я хочу в выпадающем меню.
public class OperationsList : List<string>
{
public OperationsList()
{
this.Add("");
this.Add("AL");
this.Add("ASSEM");
this.Add("BL");
this.Add("BRAKE");
this.Add("CSPUN");
this.Add("Galvanized");
this.Add("HSAW");
this.Add("IW");
this.Add("LASER");
this.Add("NEST");
this.Add("Paint");
this.Add("PB");
this.Add("Promo");
this.Add("PW");
this.Add("ROLLFRMC");
this.Add("SAW");
this.Add("SHEAR");
this.Add("VOORTMAN");
this.Add("Weld");
}
}
Мой код WPF.
<UserControl.Resources>
<Style x:Key="ToggleButton.TreeExpander" TargetType="{x:Type ToggleButton}">
<Setter Property="Margin" Value="{Binding Level, RelativeSource={RelativeSource
AncestorType={x:Type controls:TreeListViewItem}}, Converter={x:Static
controls:LevelToIndentConverter.Default}}"/>
<Setter Property="IsChecked" Value="{Binding Path=IsExpanded, RelativeSource={RelativeSource AncestorType= {x:Type controls:TreeListViewItem}}}"/>
<Setter Property="Focusable" Value="False"/>
<Setter Property="Padding" Value="0,2"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border Padding="{TemplateBinding Padding}">
<Grid Background="Transparent" SnapsToDevicePixels="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid x:Name="ArrowGrid" Grid.Column="0" Width="20">
<ContentControl x:Name="Up_Arrow" VerticalAlignment="Center" HorizontalAlignment="Center" Focusable="False">
<TextBlock Text="-"/>
</ContentControl>
<ContentControl x:Name="Down_Arrow" VerticalAlignment="Center" HorizontalAlignment="Center" Visibility="Collapsed" Focusable="False">
<TextBlock Text="+" />
</ContentControl>
</Grid>
<ContentPresenter Grid.Column="1" HorizontalAlignment="Stretch" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Center" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Path=HasItems,RelativeSource={RelativeSource AncestorType={x:Type controls:TreeListViewItem}}}" Value="False">
<Setter TargetName="ArrowGrid" Property="Visibility" Value="Hidden"/>
<Setter Property="IsHitTestVisible" Value="False"/>
</DataTrigger>
<Trigger Property="IsChecked" Value="true">
<Setter TargetName="Down_Arrow" Property="Visibility" Value="Visible" />
<Setter TargetName="Up_Arrow" Property="Visibility" Value="Collapsed" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Setter.Value>
</Setter>
</Style>
<Style x:Key="TreeListViewScrollViewerStyle" TargetType="{x:Type ScrollViewer}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollViewer">
<Grid Background="{TemplateBinding Background}" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<DockPanel Margin="{TemplateBinding Padding}">
<ScrollViewer DockPanel.Dock="Top" Focusable="false"
HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden">
<GridViewHeaderRowPresenter Columns="{Binding Path=TemplatedParent.Columns, RelativeSource={RelativeSource TemplatedParent}}"
ColumnHeaderContainerStyle="{Binding Path=TemplatedParent.ColumnHeaderContainerStyle, RelativeSource={RelativeSource TemplatedParent}}"
ColumnHeaderTemplate="{Binding Path=TemplatedParent.ColumnHeaderTemplate, RelativeSource={RelativeSource TemplatedParent}}"
ColumnHeaderTemplateSelector="{Binding Path=TemplatedParent.ColumnHeaderTemplateSelector, RelativeSource={RelativeSource TemplatedParent}}"
AllowsColumnReorder="{Binding Path=TemplatedParent.AllowsColumnReorder, RelativeSource={RelativeSource TemplatedParent}}"
ColumnHeaderContextMenu="{Binding Path=TemplatedParent.ColumnHeaderContextMenu, RelativeSource={RelativeSource TemplatedParent}}"
ColumnHeaderToolTip="{Binding Path=TemplatedParent.ColumnHeaderToolTip, RelativeSource={RelativeSource TemplatedParent}}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
<ScrollContentPresenter Name="PART_ScrollContentPresenter"
KeyboardNavigation.DirectionalNavigation="Local"
CanContentScroll="{TemplateBinding CanContentScroll}"
CanHorizontallyScroll="False"
CanVerticallyScroll="False" />
</DockPanel>
<ScrollBar Name="PART_HorizontalScrollBar"
Orientation="Horizontal"
BorderThickness="0,1,0,0"
Grid.Row="1" Grid.Column="0"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Value="{TemplateBinding HorizontalOffset}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" />
<ScrollBar Name="PART_VerticalScrollBar"
Grid.Column="1" Grid.Row="0"
BorderThickness="1,0,0,0"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Value="{TemplateBinding VerticalOffset}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" />
</Grid>
</ControlTemplate>
<Setter.Value>
</Setter>
</Style>
<Style x:Key="TreeListView.Base" TargetType="{x:Type controls:TreeListView}" >
<Setter Property="VirtualizingPanel.IsVirtualizing" Value="True" />
<Setter Property="VirtualizingPanel.VirtualizationMode" Value="Recycling" />
<Setter Property="VirtualizingPanel.ScrollUnit" Value="Item" />
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<ScrollViewer Style="{StaticResource TreeListViewScrollViewerStyle}">
<ItemsPresenter x:Name="ItemsPresenter"/>
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="TreeListViewItem.Base" TargetType="{x:Type controls:TreeListViewItem}" >
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="BorderThickness" Value="0,0,0,1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:TreeListViewItem}">
<VirtualizingStackPanel>
<Border Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
<GridViewRowPresenter x:Name="PART_Header" Content="{TemplateBinding Header}" Columns="{Binding Columns, RelativeSource={RelativeSource FindAncestor, AncestorType=controls:TreeListView}}" />
</Border>
<ItemsPresenter x:Name="ItemsHost" />
</VirtualizingStackPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="false">
<Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="Blue" />
<Setter Property="Foreground" Value="White" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="HasHeader" Value="false"/>
<Condition Property="Width" Value="Auto"/>
</MultiTrigger.Conditions>
<Setter TargetName="PART_Header" Property="MinWidth" Value="75"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="True"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="Background" Value="Gray"/>
<Setter Property="Foreground" Value="White"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" Value="0.5" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Setter.Value>
</Setter>
</Style>
<Style BasedOn="{StaticResource TreeListView.Base}" TargetType="{x:Type controls:TreeListView}" />
<Style BasedOn="{StaticResource TreeListViewItem.Base}" TargetType="{x:Type controls:TreeListViewItem}" />
</UserControl.Resources>
<controls:TreeListView HorizontalAlignment="Stretch" ItemsSource="{Binding}" >
<controls:TreeListView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding DataAssemblys}"/>
</controls:TreeListView.ItemTemplate >
<controls:TreeListView.Columns>
<GridViewColumn Header="Часть" Width="150">
<GridViewColumn.CellTemplate>
<DataTemplate>
<DataTemplate.Resources>
<DataTemplate DataType="{x:Type controls:DataParts}">
<TextBlock Text="{Binding Material}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type controls:DataAssembly}">
<TextBlock Text="{Binding Material}"/>
</DataTemplate>
</DataTemplate.Resources>
<ToggleButton Content="{Binding}" Style="{StaticResource ToggleButton.TreeExpander}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Фаза" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<DataTemplate.Resources>
<DataTemplate DataType="{x:Type controls:DataParts}">
<TextBlock Text="{Binding Phase}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type controls:DataAssembly}">
<TextBlock Text="{Binding Phase}"/>
</DataTemplate>
</DataTemplate.Resources>
<ContentPresenter Content="{Binding}" VerticalAlignment="Center"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Описание" Width="250">
<GridViewColumn.CellTemplate>
<DataTemplate>
<DataTemplate.Resources>
<DataTemplate DataType="{x:Type controls:DataParts}">
<TextBlock Text="{Binding Description}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type controls:DataAssembly}">
<TextBlock Text="{Binding Description}"/>
</DataTemplate>
</DataTemplate.Resources>
<ContentPresenter Content="{Binding}" VerticalAlignment="Center"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Количество" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<DataTemplate.Resources>
<DataTemplate DataType="{x:Type controls:DataParts}">
<TextBlock Text="{Binding Quantity}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type controls:DataAssembly}">
<TextBlock Text="{Binding Quantity}"/>
</DataTemplate>
</DataTemplate.Resources>
<ContentPresenter Content="{Binding}" VerticalAlignment="Center"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Вес" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<DataTemplate.Resources>
<DataTemplate DataType="{x:Type controls:DataParts}">
<TextBlock Text="{Binding Weight}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type controls:DataAssembly}">
<TextBlock Text="{Binding Weight}"/>
</DataTemplate>
</DataTemplate.Resources>
<ContentPresenter Content="{Binding}" VerticalAlignment="Center"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Ширина" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<DataTemplate.Resources>
<DataTemplate DataType="{x:Type controls:DataParts}">
<TextBlock Text="{Binding Width}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type controls:DataAssembly}">
<TextBlock Text="{Binding Width}"/>
</DataTemplate>
</DataTemplate.Resources>
<ContentPresenter Content="{Binding}" VerticalAlignment="Center"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Длина" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<DataTemplate.Resources>
<DataTemplate DataType="{x:Type controls:DataParts}">
<TextBlock Text="{Binding Length}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type controls:DataAssembly}">
<TextBlock Text="{Binding Length}"/>
</DataTemplate>
</DataTemplate.Resources>
<ContentPresenter Content="{Binding}" VerticalAlignment="Center"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Единица измерения" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<DataTemplate.Resources>
<DataTemplate DataType="{x:Type controls:DataParts}">
<TextBlock Text="{Binding UOM}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type controls:DataAssembly}">
<TextBlock Text="{Binding UOM}"/>
</DataTemplate>
</DataTemplate.Resources>
<ContentPresenter Content="{Binding}" VerticalAlignment="Center"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Градация" Width="75">
<GridViewColumn.CellTemplate>
<DataTemplate>
<DataTemplate.Resources>
<DataTemplate DataType="{x:Type controls:DataParts}">
<TextBlock Text="{Binding Grade}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type controls:DataAssembly}">
<TextBlock Text="{Binding Grade}"/>
</DataTemplate>
</DataTemplate.Resources>
<ContentPresenter Content="{Binding}" VerticalAlignment="Center"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Номер счета" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<DataTemplate.Resources>
<DataTemplate DataType="{x:Type controls:DataParts}">
<TextBlock Text="{Binding Bill}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type controls:DataAssembly}">
<TextBlock Text="{Binding Bill}"/>
</DataTemplate>
</DataTemplate.Resources>
<ContentPresenter Content="{Binding}" VerticalAlignment="Center"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Группировка" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<DataTemplate.Resources>
<DataTemplate DataType="{x:Type controls:DataParts}">
<TextBlock Text="{Binding Grouping}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type controls:DataAssembly}">
<TextBlock Text="{Binding Grouping}"/>
</DataTemplate>
</DataTemplate.Resources>
<ContentPresenter Content="{Binding}" VerticalAlignment="Center"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Код операции 1" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<DataTemplate.Resources>
<DataTemplate DataType="{x:Type controls:DataParts}">
<ComboBox Text="{Binding OpCode1}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type controls:DataAssembly}">
<ComboBox Text="{Binding OpCode1}"/>
</DataTemplate>
</DataTemplate.Resources>
<ContentPresenter Content="{Binding}" VerticalAlignment="Center"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Группа настройки 1" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<DataTemplate.Resources>
<DataTemplate DataType="{x:Type controls:DataParts}">
<ComboBox Text="{Binding SetupGroup1}"/>
</DataTemplate>
</DataTemplate.Resources>
<ContentPresenter Content="{Binding}" VerticalAlignment="Center"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
Ответ или решение
Как привязать список к ComboBox в DataTemplate в WPF
Привязка данных в WPF может быть несколько сложной, особенно когда речь идет о таких элементах управления, как ComboBox, используемом в DataTemplate. Давайте рассмотрим, как правильно настроить привязку ComboBox к списку значений и обеспечим возможность выбора значения по умолчанию.
1. Обозначение списка значений
Ваш класс OperationsList
, который вы привели, выглядит корректно. Он наследуется от List<string>
и инициализирует набор операций. Однако, чтобы использовать этот список в привязке, вам нужно убедиться, что экземпляр этого класса доступен в контексте привязки вашего DataContext.
public class ViewModel
{
public OperationsList AvailableOperations { get; set; }
public string SelectedOperation { get; set; }
public ViewModel()
{
AvailableOperations = new OperationsList();
SelectedOperation = AvailableOperations.First(); // или другое значение по умолчанию
}
}
2. Настройка XAML для привязки
В вашем XAML-коде, вы создаете ComboBox в ячейках GridViewColumn
. Чтобы привязать его к списку, используйте следующую структуру:
<GridViewColumn Header="Op Code 1" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox
ItemsSource="{Binding DataContext.AvailableOperations, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
SelectedItem="{Binding OpCode1, Mode=TwoWay}"
Width="100" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
3. Пояснение привязок
-
ItemsSource: Здесь используется
RelativeSource
, чтобы получить доступ кAvailableOperations
, который вы определили в вашей ViewModel. Убедитесь, чтоUserControl
является вашей корневой сущностью, и ваш ViewModel в качестве контекста данных. -
SelectedItem: Привязываем
SelectedItem
к свойствуOpCode1
, которое, в свою очередь, должно обрабатываться в ViewModel для обновления выбранного значения.
4. Правильная инициализация ViewModel
Важно, чтобы в вашем UserControl или основном окне было установлено соответствующее свойство DataContext
, чтобы привязка работала:
public partial class YourUserControl : UserControl
{
public YourUserControl()
{
InitializeComponent();
this.DataContext = new ViewModel(); // Здесь устанавливаете ваш ViewModel
}
}
5. Обработка выбранного значения по умолчанию
Если вам нужно задать значение по умолчанию для ComboBox, это можно сделать напрямую через свойство SelectedOperation
. Убедитесь, что это значение присутствует в AvailableOperations
, чтобы избежать проблем с отображением:
SelectedOperation = AvailableOperations.FirstOrDefault(); // Присвоение значения по умолчанию
Это значение отобразится в вашем ComboBox, как только он будет инициализирован.
Заключение
Таким образом, привязка списка к ComboBox внутри DataTemplate требует аккуратности в относительных привязках и правильной инициализации данных. Следуйте приведенным выше рекомендациям, и вы сможете эффективно решать привыкшие задачи привязки в WPF. Всегда проверяйте, что контекст данных установлен правильно, делайте оговорку о значении по умолчанию и, если необходимо, используйте INotifyPropertyChanged
для корректного обновления интерфейса.