WPF - Наилучшая практика для обычного управления [Метка: Входные данные]
Вопрос
Мне интересно, какой самый лучший и быстрый способ получить хорошо известную комбинацию ввода метки [или вывода, не имеет значения] в WPF.Это простая задача, просто подумайте о быстром выводе "объекта".:
Имя - Кристиан
Возраст - 28 лет
Настроение - Хорошее
Я знаю, я могу использовать сетку с текстовыми блоками.Но, честно говоря, "короткий" XAML для этого занимает почти половину страницы (определения строк, ColDefs, Grid.Col на каждой метке)
Альтернативный способ, использующий три панели стека (по горизонтали) с одной вертикальной, также кажется немного глупым.В этом случае я должен присвоить каждой метке фиксированную ширину, чтобы получить правильный отступ.И это просто "кажется" неправильным.
Итак, учитывая ситуацию выше, у вас есть пользовательский объект с 3-6 свойствами, которые вы просто хотите выгрузить в свой графический интерфейс как доступные только для чтения, как бы вы это сделали (в WPF, Silverlight тоже, если вы действительно в настроении :).
Я могу, конечно, написать usercontrol для этого.Но зачем изобретать велосипед, если он, возможно, уже есть...
И, наконец, чтобы проиллюстрировать еще больше, приведу пример, который я только что создал в реальной жизни и который послужил причиной для этого поста:
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Log Count" Width="100"/>
<TextBlock Text="{Binding LastLogRun.LogMessageCount}"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Start Time" Width="100"/>
<TextBlock Text="{Binding LastLogRun.StartTime}"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="End Time" Width="100"/>
<TextBlock Text="{Binding LastLogRun.EndTime}"/>
</StackPanel>
</StackPanel>
Решение
Если вы используете 3.5sp1, вы можете использовать StringFormat в привязке. Нечто подобное должно работать ...
<TextBlock Text="{Binding LastLogRun.LogMessageCount, StringFormat={}Log Count - {0}}" />
Другие советы
Возможно, вам следует пересмотреть свой пользовательский интерфейс. Почему вы хотите, чтобы метка - текстовое поле находилась в одной строке? Это ужасная трата пространства.
Почему бы не пометить поверх texbox? Тогда у вас есть простой интерфейс и простой XAML:
<StackPanel Orientation="Vertical">
<TextBlock>Name</TextBlock>
<TextBox />
<TextBlock>Age</TextBlock>
<TextBox />
<TextBlock>Mood</TextBlock>
<TextBox />
</StackPanel>
Добавьте немного стилей для ваших текстовых блоков, и вы получите хороший, чистый пользовательский интерфейс с очень небольшим повторением. Р>
Вы могли бы использовать общие группы размеров, чтобы получить поведение сетки автоматического определения размера двух красиво выровненных столбцов, сохраняя при этом возможность перенести сложность в UserControl.
Вот пример использования элемента управления LabeledEdit, который будет делать то, что вы ищете.Вся сложность была учтена в UserControl, и все, что вам нужно сделать, это не забыть установить Grid.IsSharedSizeScope на StackPanel:
<Window x:Class="WpfApplication5.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication5"
Name="Self" Title="Window1" Height="300" Width="300">
<StackPanel Grid.IsSharedSizeScope="True">
<local:LabeledEdit Label="Name"/>
<local:LabeledEdit Label="Age" Text="28"/>
<!-- and with databinding... -->
<local:LabeledEdit Label="Width"
Text="{Binding Width, ElementName=Self}"/>
<local:LabeledEdit Label="Height"
Text="{Binding Height, ElementName=Self}"/>
</StackPanel>
</Window>
И вот исходный код для UserControl.LabeledEdit.xaml:
<UserControl x:Class="WpfApplication5.LabeledEdit"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Name="Self">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="LabeledEdit_Labels"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="{Binding Label, ElementName=Self}"/>
<TextBox Grid.Column="1" Text="{Binding Text, ElementName=Self}"/>
</Grid>
</UserControl>
Помеченный как edit.xaml.cs:
using System.Windows;
namespace WpfApplication5
{
public partial class LabeledEdit
{
public static readonly DependencyProperty LabelProperty =
DependencyProperty.Register("Label", typeof(object), typeof(LabeledEdit));
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(LabeledEdit),
new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public LabeledEdit()
{
InitializeComponent();
}
public object Label
{
get { return GetValue(LabelProperty); }
set { SetValue(LabelProperty, value); }
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
}
}
набор инструментов silverlight имеет DataForm элемент управления, который работает довольно круто!