我有一堆控件可能会基于其他控件中的错误而启用或未启用。当控件被禁用时,我想向用户说明为什么当前被禁用。但是,我已经在使用ToolTip来获取帮助文本。因此,我想当用户将鼠标悬停在变灰的组件上时,我会在静态文本框中显示错误消息。
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
的子类,那么我将得到在三个不同的不兼容DependencyProperty中重复的代码。 (而且,实际上它们的所有示例都涉及到使用触发器,我认为这对我没有帮助吗?)
我看到还有一个Tag
属性。这是财产的合理使用吗?如果以后发现我需要另一个Tag属性怎么办?我是否应该假设这可能不会发生? (或者也许最终会实现这个目标,例如将JSON对象序列化为Tag以存储多个属性并不是没有道理的吗?)
我在这里应该做什么?
其他详细信息:
我正在使用ReactiveUI将信息从一个控件传播到另一个控件。对于每个可以显示为灰色的控件,ViewModel最终构造一个IObservable
,其项要么是控件所需的某个值(例如,一个IEnumerable<string>
可以选择ComboBox,要么可以是一个{{1 }}作为按钮有效性的证明)或错误消息。
鉴于这些可观察变量之一,我可以轻松将Unit
类型的OneWayBind
ObservableAsPropertyHelper
应用于控件的bool
属性,并希望对错误消息做类似的事情。如果要为此使用工具提示,那将非常简单:
IsEnabled
我还没有决定如何关联鼠标悬停事件。 (还没走那么远)
答案 0 :(得分:1)
我看到还有一个
Tag
属性。这是对财产的合理使用吗?
更好的方法是创建一个可以在任何元素上设置的强类型attached dependency property。只需定义一个静态类即可在其中注册属性:
public static class Metadata
{
public static readonly DependencyProperty InfoProperty = DependencyProperty.RegisterAttached(
"Info",
typeof(string),
typeof(Metadata),
new FrameworkPropertyMetadata(null));
public static void SetInfo(UIElement element, string value) => element.SetValue(InfoProperty, value);
public static string GetInfo(UIElement element) => (string)element.GetValue(InfoProperty);
}
您可以像这样在任何UIElement
上进行设置:
<TextBox IsEnabled="False" TextWrapping="Wrap" Width="200" FontSize="10" Height="50"
local:Metadata.Info="Mouse over an item that's grayed out and the reason why will appear here.">
</TextBox>
您可以使用GetInfo
方法以编程方式获取值:
string info = Metadata.GetInfo(theControl);