Какой самый минимальный способ динамического обмена UIElement
s в определенном «слоте» в пользовательском интерфейсе? У меня есть число UIElement
s и на основе некоторых внешних привязок данных (например, выбор combobox). Я хочу, чтобы один из них отображался, а тот, который в настоящее время был скрыт, был скрыт. Таким образом, поведение похоже на TabControl
, но без вкладки tabstrim, chrome и tabitem. Поэтому я мог бы использовать TabControl
и переопределить шаблон управления. Но действительно ли это самый минимальный подход?Управление обменом UIElements в WPF
ответ
У вас есть несколько вариантов. Как сказал Брайан, Data Template Selectors может определенно работать, хотя я решил, что они часто переборщит. Возьмем ваш пример, например, если вы хотите привязать видимость элемента к выбору в ComboBox
, я предпочел бы вместо этого ValueConverter
. Пропустите ComboBox.SelectedItem
к Converter
и он возвращает значение видимости:
public class MyObjectToVisibleOrCollapsed : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is MyObject)
{
var myObject = (MyObject)value;
if (myObject.SomeState)
{
return Visibility.Visible;
}
}
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
Теперь в ваших Window.Resources, создать экземпляр ValueConverter
и Привязать элемент к ComboBox.SelectedItem
с помощью ValueConverter
экземпляра:
<local:MyObjectToVisibleOrCollapsed x:Key="myObjectToVisibleOrCollapsed"/>
<DataTemplate x:Key="MyTemplate">
<TextBlock Text="{Binding Path=myText}"
x:Name="MyText"
Visibility="{Binding ElementName=MyComboBox, Path=SelectedItem, Converter={StaticResource myObjectToVisibleOrCollapsed}, Mode=Default}" />
</DataTemplate>
И, конечно, вы можете повторно использовать ValueConverter
для всех элементов вашего DataTemplate
(и, если их много, то подход выбора шаблона данных становится более желательным).
[Отказ от ответственности: выше код был хэшируется из памяти и не тестируется - это, возможно, потребуется немного настройки]
<ContentControl Content="{Binding SomePropertyThatYieldsTheContent}"/>
Как я сделать это, чтобы слой элементов друг на друга и программно изменить их видимость собственности от Видна Рухнул и обратно по мере необходимости.
Наши дизайнеры не очень хороши в C#, но это те, которые определяют пользовательский интерфейс. – bitbonk
Я не знаю, если это является наиболее емким способом, но если вы используете DataTemplate
, вы могли бы использовать DataTrigger
с (предположение в том, что первоначальная видимость Collapsed
):
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=SourceProperty.ValueType}">
<DataTrigger.Value>
<pm:ValueType>Text</pm:ValueType>
</DataTrigger.Value>
<Setter TargetName="TextEditor" Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=SourceProperty.ValueType}">
<DataTrigger.Value>
<pm:ValueType>Logical</pm:ValueType>
</DataTrigger.Value>
<Setter TargetName="LogicalEditor" Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=SourceProperty.ValueType}">
<DataTrigger.Value>
<pm:ValueType>DateTime</pm:ValueType>
</DataTrigger.Value>
<Setter TargetName="DateEditor" Property="Visibility" Value="Visible" />
</DataTrigger>
...
Этот метод работает очень хорошо, если у вас есть только несколько «режимов», например. режим «редактирования» и режим «только чтение». Мне нравится устанавливать видимость на Visible или Hidden и иметь несколько элементов в одной ячейке сетки, поэтому у вас нет других элементов пользовательского интерфейса при изменении режима. –
Посмотрите на Data Template Selectors, у Bea Stollnitz есть хороший пост here. В основном вы будете использовать ContentPresenter
в каждом слоте пользовательского интерфейса, а затем используйте свойство ContentTemplateSelector
, чтобы определить, какой шаблонный селектор вы будете использовать.
Я создавать собственные пользовательские элементы управления для каждого возможного «зрения».
Их видимость изменяется с использованием C#, тыс. Требуется небольшое кодирование.
Основная причина такого подхода - простота разработки - дизайнер фокусируется на определенном виде, а не на множестве всех возможных элементов управления, которые будут там.
Основываясь на ответе на http://stackoverflow.com/questions/1287995, я думаю, что здесь лучше будет использовать ContentPresenter. – Wilka