Мне нужно иметь комбинированный список с двумя значениями.Первый должен иметь собственное имя, а второй должен использовать свойства нижележащего связанного объекта.Оба элемента являются значениями на ВМ, и я могу связать их все успешно.
XAML
<Window x:Class="StaticComboBox.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:StaticComboBox"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance local:StaticUIVm}"
Title="MainWindow"
Height="450"
Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<ComboBox Grid.Row="1"
SelectedValuePath="Tag"
SelectedValue="{Binding SelectedValue, Mode=TwoWay}">
<ComboBox.Items>
<ComboBoxItem Content="Custom Display Text 111"
Tag="{Binding FirstValue}" />
<ComboBoxItem Content="{Binding SecondValue.Item2}"
Tag="{Binding SecondValue}" />
</ComboBox.Items>
</ComboBox>
</Grid>
</Window>
XAML.cs
using System.Windows;
namespace StaticComboBox
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new StaticUIVm();
}
}
}
StaticUIVm.cs
using StaticComboBox.Annotations;
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace StaticComboBox
{
public class StaticUIVm : INotifyPropertyChanged
{
public Tuple<long, string> FirstValue { get; set; }
public Tuple<long, string> SecondValue { get; set; }
private Tuple<long, string> _selectedValue;
public Tuple<long, string> SelectedValue
{
get { return _selectedValue; }
set
{
_selectedValue = value;
OnPropertyChanged();
}
}
public StaticUIVm()
{
FirstValue = new Tuple<long, string>(1, "Some Static Value");
SecondValue = new Tuple<long, string>(2, "Some Other Static Value");
SelectedValue = FirstValue;
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Моя проблема заключается в том, что, несмотря на то, что привязки работают правильно для элементов и отображения и когда я, как пользователь, выбираю значение, комбинированный список не отображается 't отражает правильный выбор при инициализации класса VM.Смысл, он не выбирает FirstValue.Это не имеет смысла для меня, поскольку ссылка должна быть точно такой же, и я подтвердил, что значение на виртуальной машине фактически изменяется во время инициализации.Я определенно инициализировал значения в конструкторе, и они уважались и отображались при загрузке, поэтому я немного запутался в том, где я ошибаюсь.
РЕДАКТИРОВАТЬ
Я принял ответ mm8, но мне пришлось внести несколько дополнительных изменений в XAML, чтобы заставить его вести себя по мере необходимости.Мне нужно было иметь возможность запускать пользовательский текст на основе значения идентификатора элементов, который был установлен во время выполнения.Из-за этого простой DataTrigger не будет работать, поэтому мне пришлось использовать MultiBinding.MultiBinding прервал отображение, когда был выбран элемент (как описано в ComboBox.ItemTemplate, не отображающий выделение должным образом ), поэтому мне пришлось установить IsEditable в false.Полный комбинированный список приведен ниже.
<ComboBox Grid.Row="2"
Grid.Column="1"
IsEditable="False"
ItemsSource="{Binding ItemSource}"
SelectedItem="{Binding SelectedValue}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Text"
Value="{Binding Name}" />
<Style.Triggers>
<DataTrigger Value="True">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource LongEqualToLongMultiBindingDisplayConverter}">
<Binding Path="Id" />
<Binding Path="DataContext.FirstValue.Id" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MyControl}}" />
</MultiBinding>
</DataTrigger.Binding>
<Setter Property="Text"
Value="Custom Display Text 111" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Этот XAML в сочетании с предложениями из ответа mm8 (настройка коллекции, которая инициализируется во время выполнения из двух предоставленных значений) сделали свое дело.