ItemTemplate của một ListBox được sao chép vào ContentTemplate của một ListBoxItem trong quá trình tạo giao diện người dùng. Có nghĩa là mã của bạn tương đương với các mã sau.
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<DockPanel>
<TextBlock><ContentPresenter /></TextBlock>
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBoxItem Content="Hello" />
<ListBoxItem Content="World" />
</ListBox>
Tuy nhiên, bạn thêm trực tiếp ListBoxItems để điều này không đúng 100%.
(ItemTemplate và ItemTemplateSelector được bỏ qua cho các mục đã thuộc loại vùng chứa của ItemsControl; Type = 'ListBoxItem')
Để giải thích lý do tại sao Visual Studio bị treo. Đầu tiên, nó chỉ đổ vỡ khi ListBox đang được phổ biến, vì vậy điều này sẽ chỉ xảy ra khi thêm ListBoxItem trực tiếp vào Xaml (Ứng dụng của bạn sẽ vẫn bị lỗi nhưng không phải VS). ContentPresenter là nơi mà Template cho ListBox đang chèn ContentTemplate. Vì vậy, nếu chúng ta có điều này
<Style TargetType="ListBoxItem">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock><ContentPresenter /></TextBlock>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
và chúng tôi không thay đổi Template để nó trông giống như thế này (phiên bản rút ngắn đáng)
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
Chúng tôi sẽ nhận được
<ContentPresenter/> -> <TextBlock><ContentPresenter /></TextBlock> ->
<TextBlock><TextBlock><ContentPresenter /></TextBlock></TextBlock>
và vân vân . Nó không bao giờ dừng lại, và Visual Studio bị treo. Nếu chúng tôi thay đổi Mẫu thành số này
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<TextBlock Text="No ContentPresenter Here"/>
</ControlTemplate>
</Setter.Value>
</Setter>
chúng tôi không gặp sự cố nào do ContentPresenter không bao giờ được sử dụng.
(Nghĩ rằng tôi đã bị hỏng Studio hàng chục lần trong khi thử điều này :)
Vì vậy, trong trường hợp của bạn, bạn nên sử dụng Mẫu thay vì ContentTemplate.
<ListBox>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<DockPanel>
<TextBlock><ContentPresenter /></TextBlock>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBoxItem Content="Hello" />
<ListBoxItem Content="World" />
</ListBox>
thử mã của bạn và nó đã bị rơi chứ :) –
Bạn không thể sử dụng ContentPresenter trong ContentTemplate vì nó là loại mã đệ quy, ContentPresenter sẽ một lần nữa nạp ContentTemplate, và ContentTemplate sẽ một lần nữa nạp ContentPresenter và vân vân .. .. –