Пишу чат. Отрисовал шаблон сообщения в 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"/>
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Какие существуют виды рекламных бордов и как выбрать подходящий?
Использую awesomium вместо стандартного компонента браузераНужно изменить user agent
Нужно достать параметры некоторого объекта изdwg файла
Создал новый проект, сделал форму, добавил кнопку(search)Хочу при нажатии на кнопку открывать форму(searchUsers) из другой сборки