Пишу чат. Отрисовал шаблон сообщения в usercontrol.
<UserControl x:Class="ChatMessage.MessageView"
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:ChatMessage"
mc:Ignorable="d"
d:DesignHeight="44" d:DesignWidth="250">
<Grid>
<StackPanel Margin="0 4 0 0" Width="36" Height="36" VerticalAlignment="Top" HorizontalAlignment="Left" Orientation="Horizontal">
<Image Source="Resources/admin.png"/>
</StackPanel>
<StackPanel Margin="36 0 0 0" Height="22" HorizontalAlignment="Left" Orientation="Horizontal" VerticalAlignment="Top">
<TextBlock Margin="6 0 0 4" FontSize="15" FontFamily="Lato" FontWeight="Bold">Username</TextBlock>
<TextBlock Margin="4 4 0 4" FontSize="11" FontFamily="Lato" FontWeight="Light">8:23 AM</TextBlock>
</StackPanel>
<StackPanel Margin="42 22 0 0" Orientation="Horizontal">
<TextBlock FontFamily="Loto" FontSize="13" FontWeight="Regular" Text="Hey!What's going on?"/>
</StackPanel>
</Grid>
научился вызывать его в codebehind mainwindow и добавлять в listview
MessageView mv = new MessageView();
ListMessage.Items.Add(mv);
полагаю теперь самая сложная задача, как написать код, чтобы при вызове usercontrol, в codebehind mainwindow, к нему добавлялся image, username, date и message в соответствующие поля шаблона usercontrol.
Смотрите. Для того, чтобы параметризировать ваш UserControl, вам нужно добавить в него свойства. Точнее, dependency property. Знаете, как это делается? (Если нет, почитайте про сниппеты, вам нужен propdp.)
Итак, не мудрствуя лукаво, нам понадобятся свойства string UserName, DateTime Date и string Text. Когда вы добавите их в ваш UserControl, у вас получится что-то вроде такого:
public string UserName
{
get { return (string)GetValue(UserNameProperty); }
set { SetValue(UserNameProperty, value); }
}
public static readonly DependencyProperty UserNameProperty =
DependencyProperty.Register("UserName", typeof(string), typeof(MessageView));
Теперь, значения свойств нужно отобразить. Для этого немного поменяем XAML-разметку:
<Grid DataContext="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType=UserControl}}"
TextBlock.FontFamily="Loto">
<!-- начальный кусок пропустил -->
<StackPanel Margin="36 0 0 0" Height="22"
HorizontalAlignment="Left" Orientation="Horizontal" VerticalAlignment="Top">
<TextBlock Margin="6 0 0 4" FontSize="15" FontWeight="Bold"
Text="{Binding UserName}" />
<TextBlock Margin="4 4 0 4" FontSize="11" FontWeight="Light"
Text="{Binding Date, StringFormat=t}"/>
</StackPanel>
<StackPanel Margin="42 22 0 0" Orientation="Horizontal">
<TextBlock FontSize="13" FontWeight="Regular"
Text="{Binding Text}"/>
</StackPanel>
</Grid>
Объяснение:
DataContext на сам UserControl, чтобы привязываться к свойствам было проще. (Привязка ведётся по умолчанию к DataContext'у.)
DataContext установлен внутри, не у самого UserControl'а, т. к. пользователь обычно хочет дать свой DataContext всему контролу, чтобы привязывать его свойства.FontFamily наружу, чтобы не устанавливать его каждый разUserName, Date и Text привязываются к свойствам через Binding. Вручную их больше устанавливать не нужно.
Date привязывается с указанием формата строки. t означает короткий формат, содержащий только время.Теперь, как этим пользоваться? Очень просто. Если вы не используете MVVM, а создаёте контролы в code-behind, то
MessageView mv = new MessageView()
{
UserName = "Василий",
Date = new DateTime(2017, 11, 16, 8, 23, 00),
Text = "Hey! What's going on?"
};
Если вы пользуетесь MVVM, у вас будет что-то наподобие
<ListView ItemsSource="{Binding AllMessages}">
<ListView.ItemTemplate>
<DataTemplate>
<local:MessageView
UserName="{Binding UserName}" Text="{Binding Text}" Date="{Binding Date}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
@VladD: В общем потестил, главное в listview отключить горизонтальный скрол, а все остальное ни как не влияет. Если установить максимальную длину строки у textblock 'a, то текст нужно еще выравнивать по левому краю иначе все оставшееся место из maxwidth, которое не занял текст он использует как пропорциональный margin по левому и правому краю, то есть как бы произойдет центрирование текста. Конечный вариант выглядит следующим образом:
<TextBlock Margin="42 22 0 0"
FontSize="13" FontWeight="Regular"
TextWrapping="Wrap" Text="{Binding Text}"/>
<ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled"
Name="ListMessage" Grid.Row="0"/>
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости