Я пытаюсь поместить StackPanel в ListBox, а это в Grid, который является частью UserControl.
Пока что я придумал следующий XAML, но я не могу исправить ширину. Когда вы посмотрите на снимок экрана, вы увидите, что StackPanel на несколько пикселей превышает ширину. Я пробовал HorizontalAlignment=Stretch на каждом элементе, но на Width = {Binding...} удалось ограничить ширину, хотя и не идеально. Что я скучаю?
<UserControl x:Class = "Reusable.Apps.ExceptionControl"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:local = "clr-namespace:Reusable.Apps"
mc:Ignorable = "d"
d:DesignHeight = "450" d:DesignWidth = "800" Width = "{Binding (Window.Width), RelativeSource = {RelativeSource FindAncestor, AncestorType = {x:Type Window}}}">
<UserControl.Resources>
<local:ExceptionVisualizerData x:Key = "DesignViewModel" />
<Style TargetType = "TextBlock" x:Key = "NameStyle">
<Setter Property = "FontSize" Value = "20"/>
<Setter Property = "FontWeight" Value = "Bold"/>
<Setter Property = "FontFamily" Value = "Consolas"/>
<Setter Property = "Foreground" Value = "DarkMagenta"/>
</Style>
<Style TargetType = "TextBlock" x:Key = "MessageStyle">
<Setter Property = "FontSize" Value = "16"></Setter>
<Setter Property = "FontFamily" Value = "Segoe UI"/>
<Setter Property = "TextWrapping" Value = "Wrap"/>
</Style>
</UserControl.Resources>
<Grid Width = "{Binding (UserControl.Width), RelativeSource = {RelativeSource FindAncestor, AncestorType = {x:Type UserControl}}}">
<ListBox ItemsSource = "{Binding Exceptions}" d:DataContext = "{Binding Source = {StaticResource DesignViewModel}}" Width = "{Binding (Grid.Width), RelativeSource = {RelativeSource FindAncestor, AncestorType = {x:Type Grid}}}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Width = "{Binding (ListBox.Width), RelativeSource = {RelativeSource FindAncestor, AncestorType = {x:Type ListBox}}}">
<TextBlock Text = "{Binding Name}" Style = "{StaticResource NameStyle}" />
<TextBlock Text = "{Binding Message}" Style = "{StaticResource MessageStyle}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>





Вместо обозначения ListBox укажите ширину ListBoxItem.
<StackPanel Width = "{Binding (ListBoxItem.Width), RelativeSource = {RelativeSource FindAncestor, AncestorType = {x:Type ListBoxItem}}}">
Это сработало в моем местном. Требуется ли ширина привязки? Я имею в виду убрать Ширину с StackPanel и проверить.
На самом деле я нахожу привязку Width уродливой, но это единственный способ сделать это на полпути. Я бы лучше все это выбросил, если бы было что-то получше.
Это было близко. Использование ListBoxItem было хорошим треком, но не в том месте ;-)
Интересно, почему это не сработало, даже если мы связываемся с ListBoxItem.Wdth
Я предполагаю, потому что сам ListBoxItem был слишком широким, поэтому привязка к его Width не решила его (на этот раз?). По всей видимости, он был неограниченной ширины.
Как бы то ни было, вам удалось найти решение. Отметьте свое решение как ответ, чтобы любой, кто страдает, как вы, быстро получил ответ. - :)
Хорошо, мне просто нужно подождать 19 часов, пока это будет разрешено, спасибо за ваш вклад, это был хороший намек, поскольку я раньше не знал о ListBoxItem ;-)
Похоже, вам следует избавиться от всех привязок ширины и просто оставить поле вокруг StackPanel, например:
<StackPanel Margin = "10" >
--- ОБНОВЛЕНО -
Разочарование - правильное слово. Хорошо, вот решение.
(1) Замените StackPanel сеткой.
(2) В ListBox установите для ScrollViewer.HorizontalScrollBarVisibility значение «Disabled».
<ListBox ScrollViewer.HorizontalScrollBarVisibility = "Disabled">
<Grid Margin = "10" >
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Row = "0" Text = "Title" Style = "{StaticResource NameStyle}" />
<TextBlock Grid.Row = "1" TextWrapping = "Wrap" Text = "lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text lots of text " Style = "{StaticResource MessageStyle}" />
</Grid>
</ListBox>
Это должно помочь.
ммм ... Я удалил все привязки Width, и это определенно проклятый StackPanel, и когда он не привязан к ListBox, он слишком широкий, и перенос текста не работает, а когда он привязан, он всегда на несколько пикселей шире. Это так безумно и неприятно :-(
Наконец-то я понял! Я нашел аналогичный вопрос и адаптировал его отвечать для своих нужд:
<Grid >
<ListBox ItemsSource = "{Binding Exceptions}" d:DataContext = "{Binding Source = {StaticResource DesignViewModel}}" Margin = "30" >
<ListBox.ItemContainerStyle>
<Style TargetType = "ListBoxItem">
<Setter Property = "Width" Value = "{Binding (Grid.ActualWidth), RelativeSource = {RelativeSource FindAncestor, AncestorType = {x:Type Grid}}}" />
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text = "{Binding Name}" Style = "{StaticResource NameStyle}" />
<TextBlock Text = "{Binding Message}" Style = "{StaticResource MessageStyle}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Уловка заключалась в том, чтобы связать Width из ListBoxItem с родителем. Святая корова! Это было сложно. Теперь он также хорошо масштабируется при изменении размера окна.
Причина перекрытия связана с шаблоном по умолчанию для ListBoxItem, для которого Padding установлено значение «4,1» и BorderThickness равно «1» как для самого себя, так и для внутреннего объекта Border. Вы можете использовать такой инструмент, как WPF Snoop, чтобы увидеть это.
Решение заключается в привязке к ActualWidth следующего уровня контейнера, в данном случае ContentPresenter.
<ListBox ItemsSource = "{Binding DataItems}"
ScrollViewer.HorizontalScrollBarVisibility = "Disabled"
HorizontalContentAlignment = "Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Background = "Yellow"
Width = "{Binding RelativeSource = {RelativeSource FindAncestor,
AncestorType = {x:Type ContentPresenter}},
Path=ActualWidth}">
<Grid.RowDefinitions>
<RowDefinition Height = "Auto" />
<RowDefinition Height = "Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row = "0" Text = "{Binding Id}" />
<TextBlock Grid.Row = "1" Text = "{Binding Description}" TextWrapping = "Wrap" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Обратите внимание на свойства, установленные для ListBox, которые предотвращают рост содержимого за пределы ширины ListBox и принудительное изменение размера содержимого по мере увеличения ширины ListBox.
К сожалению, это не действует :-(