【问题标题】:SelectedItem binding stops working when using custom DataTemplate on Listbox在 Listbox 上使用自定义 DataTemplate 时,SelectedItem 绑定停止工作
【发布时间】:2016-05-25 11:48:42
【问题描述】:

我有一个简单的ListBox,它的条目是从视图模型中的ObservableCollection<T> 绑定的。此外,我还绑定了一个 SelectedItem 属性。

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

对于一些需求我需要修改实际的列表框项,所以我做了一个自定义DataTemplate这样的:

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

然而,只要有DataTemplateSelectedItem 绑定就会停止工作。无论我做什么,它都不会触发。如果我把整个DataTemplate 拿走,它就会重新开始工作。既然我有一个自定义的ListBoxItem,我是否必须以某种方式将自己绑定到ListBoxSelectedItem 属性?还是我只是在这里遗漏了什么?


完整代码

<ListBox x:Name="Entries" ItemsSource="{Binding Entries}" Grid.Column="1" Margin="5, 5, 0, 5" SelectedItem="{Binding SelectedEntry}" >
        <ListBox.ItemContainerStyle>
            <Style TargetType="ListBoxItem">
                <Setter Property="Height" Value="5" />
                <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>
                <ListBoxItem Background="{Binding EntryColor}" 
                             ToolTipService.InitialShowDelay="0" 
                             ToolTip="{Binding SequenceNumber, StringFormat=Sequence {0:D12}}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

【问题讨论】:

  • 你不需要ItemTemplate。只需将这些属性放入样式中即可。

标签: c# wpf mvvm listbox caliburn.micro


【解决方案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 时可能存在问题,但我不完全确定这里发生了什么。无论如何,模板中不需要ListViewItems - ListView 会自动创建需要的。

附录

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

所有这些中的DataContextItem,这就是我们想要的。

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

内部ContentPresenterTextBlockDataContext只是字符串值,导致绑定失败。

然后我想改变Content绑定:

<DataTemplate>
    <ListViewItem
        Background="{Binding EntryColor}"
        FontSize="20"
        Content="{Binding}"
        ToolTipService.InitialShowDelay="0"
        ToolTip="{Binding SequenceNumber, StringFormat=Sequence {0:D12}}" />
</DataTemplate>

这修复了内部ContentPresenterDataContext,但不是它的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 提供了适当的DataContext

尽管如此,SelectedItem 绑定仍然无法正常工作,所以经过一番探索之后,我并没有那么聪明...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-30
    • 2012-08-26
    • 2010-12-26
    • 2011-01-02
    • 1970-01-01
    相关资源
    最近更新 更多