在Listbox上使用自定义DataTemplate时,SelectedItem绑定停止工作

时间:2016-05-25 11:48:42

标签: c# wpf mvvm listbox caliburn.micro

我有一个简单的ListBox条目来自视图模型中的ObservableCollection<T>。另外,我绑定了一个 SelectedItem 属性。

<ListBox ItemsSource="{Binding Entries}" SelectedItem="{Binding SelectedEntry}" />

对于某些要求,我需要修改实际的列表框项,因此我制作了这样的自定义DataTemplate

<DataTemplate>
    <ListBoxItem ... />
</DataTemplate>

但是,只要DataTemplate存在, SelectedItem 绑定就会停止工作。无论我做什么,它都根本不会发射。如果我把整个DataTemplate拿走,它就会重新开始工作。由于我有一个自定义ListBoxItem,我是否必须以某种方式将自己绑定到SelectedItem的{​​{1}}属性?或者我只是在这里遗漏了什么?

完整代码

ListBox

1 个答案:

答案 0 :(得分:1)

在您的模板中,将ListViewItem替换为其他内容,例如TextBlock。这对我有用(与你的代码类似):

档案:

public class Item
{
    public Brush EntryColor { get; set; }

    public long SequenceNumber { get; set; }

    public string Text => $"Item {SequenceNumber}";

    public override string ToString()
    {
        return Text;
    }
}

列表:

public class List
{
    public IList<Item> Entries => new List<Item>
        {
            new Item { EntryColor = Brushes.Cyan, SequenceNumber = 1 },
            new Item { EntryColor = Brushes.Red, SequenceNumber = 2 },
            new Item { EntryColor = Brushes.Orange, SequenceNumber = 3 },
        };

    public Item SelectedItem { get; set; }
}

XAML:

<StackPanel>
    <StackPanel.DataContext>
        <local:List />
    </StackPanel.DataContext>
    <ListBox x:Name="Entries" ItemsSource="{Binding Entries}" Grid.Column="1" Margin="5, 5, 0, 5" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" >
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Setter Property="Height" Value="50" />
                <Setter Property="Margin" Value="0" />
                <Setter Property="Padding" Value="0" />
                <Setter Property="BorderThickness" Value="0" />
                <Setter Property="HorizontalContentAlignment" Value="Stretch" />
            </Style>
        </ListBox.ItemContainerStyle>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock
                    Background="{Binding EntryColor}"
                    FontSize="20"
                    Text="{Binding Text}"
                    ToolTipService.InitialShowDelay="0"
                    ToolTip="{Binding SequenceNumber, StringFormat=Sequence {0:D12}}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <TextBlock Text="{Binding SelectedItem}" />
</StackPanel>

我怀疑SelectedItem绑定在将ItemListBoxItem相关联时可能会出现问题,但我并不完全确定此处发生了什么。无论如何,模板中不需要ListViewItem - ListView会自动创建所需的文件。

<强>附录

当模板包含TextBlock时,可视化树如下所示:

Visual tree with TextBlock

所有这些DataContext都是Item,这就是我们想要的。

当模板包含ListViewItem时,我们会得到两个

Visual tree with ListBoxItem

内部DataContextContentPresenter的{​​{1}}只是字符串值,这会导致绑定失败。

然后我想改变TextBlock绑定:

Content

这会修复内部<DataTemplate> <ListViewItem Background="{Binding EntryColor}" FontSize="20" Content="{Binding}" ToolTipService.InitialShowDelay="0" ToolTip="{Binding SequenceNumber, StringFormat=Sequence {0:D12}}" /> </DataTemplate> 的{​​{1}},但不修复其DataContext。最后一次尝试:

ContentPresenter

... TextBlock提供适当的<DataTemplate> <ListViewItem Background="{Binding EntryColor}" FontSize="20" ToolTipService.InitialShowDelay="0" ToolTip="{Binding SequenceNumber}"> <ListViewItem.Content> <TextBlock Text="{Binding Text}"/> </ListViewItem.Content> </ListViewItem> </DataTemplate>

TextBlock绑定仍然无法正常工作,所以在经过这段时间后,我并没有那么明智......