У меня есть несколько элементов управления, которые могут включаться или не включаться в зависимости от ошибок других элементов управления. Когда элемент управления отключен, я хочу дать пользователю объяснение, почему он в настоящее время отключен. Тем не менее, я уже использую подсказку для текста справки. Поэтому я подумал, что сообщения об ошибках будут появляться в статическом текстовом поле, когда пользователь наведет курсор на серый компонент.
Упрощенный xaml:
<StackPanel Margin="10 10 10 10">
<TextBox x:Name="thtkDirTextBox" ToolTip="yadda yadda help text"/>
<TextBox x:Name="tououDatTextBox" ToolTip="yadda yadda help text"/>
<ComboBox x:Name="touhouExeSelector" ToolTip="yadda yadda help text"/>
<ComboBox x:Name="stageSelector" ToolTip="yadda yadda help text"/>
<ComboBox x:Name="sceneSelector" ToolTip="yadda yadda help text"/>
<GroupBox Header="Errors">
<TextBox IsEnabled="False" TextWrapping="Wrap" Width="200" FontSize="10" Height="50">
Mouse over an item that's grayed out and the reason why will appear here.
</TextBox>
</GroupBox>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="Save as..." ToolTip="yadda yadda help text"></Button>
<Button Content="Quick Play" ToolTip="yadda yadda help text"></Button>
</StackPanel>
</StackPanel>
Важно, чтобы это работало, каждый компонент должен быть связан с пользовательским фрагментом метаданных для хранения сообщения об ошибке. (Разные элементы управления могут иметь разные причины для недоступности!)
Я читал о DependencyProperties, но, похоже, что для их использования требуется подкласс элемента управления. Если мне нужно создать подклассы TextBox
, ComboBox
и Button
, то я получу дублированный код для трех разных несовместимых свойств DependencyProperties. (кроме того, практически все их примеры включают использование триггеров, которые, я не думаю, могут мне здесь помочь?)
Я вижу, что есть также свойство Tag
. Это добросовестное использование имущества? Что если позже я обнаружу, что мне нужно другое свойство Tag? Должен ли я просто предположить, что это, вероятно, не произойдет? (Или, может быть, если это в конечном итоге приведет к этому, возможно, не исключено, например, сериализовать объекты JSON в Tag для хранения нескольких атрибутов?)
Что мне здесь делать?
Дополнительные сведения:
Я использую ReactiveUI для распространения информации от одного элемента управления к другому. Для каждого элемента управления, который может быть выделен серым цветом, ViewModel в конечном итоге создает IObservable
, элементы которого либо являются некоторым значением, необходимым для элемента управления (например, IEnumerable<string>
с возможностью выбора для ComboBox, либо, возможно, просто Unit
в качестве доказательства срок действия кнопки) или сообщение об ошибке.
Учитывая одну из этих наблюдаемых, я легко могу OneWayBind
a ObservableAsPropertyHelper
типа bool
со свойством IsEnabled
элемента управления и надеюсь сделать что-то подобное для сообщения об ошибке. Если бы я использовал для этого всплывающие подсказки, это было бы довольно просто:
// ViewModel
this.stageSelectorErrorMessage =
this.stageSelectorEithers
.Select(either => either.Error) // string on failure, null on success
.ScheduleOn(RxApp.MainThreadScheduler)
.ToProperty(this, x => x.StageSelectorErrorMessage);
// View
this.WhenActivated(disposableRegistration => {
// ...
this.OneWayBind(this.ViewModel,
viewModel => viewModel.StageSelectorErrorMessage,
view => view.stageSelector.ToolTip
).DisposeWith(disposableRegistration);
})
Я еще не решил, как подключить события наведения мыши. (не зашел так далеко)