1

ツールチップを意図したとおりに使用したい。しかし、エラーが発生したときにエラーメッセージを表示するように変更し、エラーが修正されたら元に戻す必要があります。

そこで、ツールチップを保持する添付プロパティを作成しました。ツールチップを添付プロパティに割り当て、スタイルを使用してそれをツールチップ プロパティにコピーします。エラーがある場合、スタイルは代わりにツールチップをエラー メッセージに設定します。

したがって、ツールチップにエラー メッセージを設定するトリガーは次のとおりです。

<Trigger Property="Validation.HasError"
                Value="true">
<Setter Property="BorderBrush"
                Value="{DynamicResource controls-errorBorderBrush}" />
<Setter Property="ToolTip"
                Value="{Binding RelativeSource={x:Static RelativeSource.Self},
    Path=(Validation.Errors)[0].ErrorContent}" />
</Trigger>

それはかなり簡単に思えます(そしてうまくいきます)

エラーが修正されたら、元に戻します (これは機能しません)。

<Trigger Property="Validation.HasError"
Value="false">
<Setter Property="ToolTip"
    Value="{Binding Path=(wpfMisc:myCtrl.tooltipValue)}" />
</Trigger>

そして、私が持っているxamlファイルには:

<TextBox Text="this is a textbox with a myMisc based tooltip"
 Name="txtTooltip2"
 wpfMisc:myCtrl.tooltipValue="Tooltip Test tooltip" />

もちろん、情報が正しく保存されていないように見えるため、添付されたプロパティに問題がある可能性が最も高いです。そのコードは次のとおりです。

public static string GettooltipValue(DependencyObject obj)
{
string value = obj.GetValue(tooltipValueProperty).ToString() ;
value = value.trimNull() ; // extension method to insure at least an empty string
return value ;
}

public static void SettooltipValue(DependencyObject obj, string value)
{
obj.SetValue(tooltipValueProperty, value.trimNull() );
}

public static readonly DependencyProperty tooltipValueProperty =
DependencyProperty.RegisterAttached("tooltipValue",
typeof(string),
typeof(myCtrl),
new UIPropertyMetadata(string.Empty));

したがって、UIPropertyMetaData で別のものを使用する必要があると思いますが、何を使用するかはわかりません。それとも私のアプローチ全体が間違っていますか?

すべてのデータ フィールドにデータ固有のツールチップが必要です。

エラー時にツールチップをタグプロパティに移動することでこれを機能させましたが、他のコードがタグを特別な方法で使用したい場合に問題が発生することを知っているため、そのままにしたくありませんでした仕方。

また、コードの一部が冗長であることも知っています-デバッグの副作用です...

また、myCtrl の別の依存関係プロパティは正常に機能しているため、xmlns などの参照が正しいことはわかっています。

さらに調査した結果、出力ウィンドウに次のようなメッセージが表示されました: System.Windows.Data Error: 17 : Cannot get 'tooltipValue' value (type 'String') from '' (type 'layoutSettingsViewModel'). BindingExpression:パス=(0); DataItem='layoutSettingsViewModel' (HashCode=46457861); ターゲット要素は 'TextBox' (Name='') です。ターゲット プロパティは 'ToolTip' (タイプ 'Object') InvalidCastException:'System.InvalidCastException: タイプ 'client.Models.layoutSettings.layoutSettingsViewModel' のオブジェクトをタイプ 'System.Windows.DependencyObject' にキャストできません。

layoutSettingsViewModel は xaml ビューです。したがって、ビュー自体が何らかの形でコントロールの代わりに値を取得していると思います....確かではありません-あなたの1人がそれが何を意味するのか、そしてその理由を正確に知っていると思います...新しい言語...

とにかく、どんな助けや提案も大歓迎です。

4

2 に答える 2

0

同様の機能を作成しましたが、Buttonコントロール用です。Buttonこのための作業コードを提供します。使用するコントロールに置き換えるだけです。AttachedProperty無効化されたメッセージ用に1 つ作成ToolTipし、元の値を「記憶」するために別のものを作成する必要がありました。

private static readonly DependencyPropertyKey originalToolTipPropertyKey = DependencyProperty.RegisterAttachedReadOnly("OriginalToolTip", typeof(string), typeof(ButtonProperties), new FrameworkPropertyMetadata(default(string)));

/// <summary>
/// Contains the original Button.ToolTip value to display when the Button.IsEnabled property value is set to true.
/// </summary>
public static readonly DependencyProperty OriginalToolTipProperty = originalToolTipPropertyKey.DependencyProperty;

/// <summary>
/// Gets the value of the OriginalToolTip property.
/// </summary>
/// <param name="dependencyObject">The DependencyObject to return the OriginalToolTip property value from.</param>
/// <returns>The value of the OriginalToolTip property.</returns>
public static string GetOriginalToolTip(DependencyObject dependencyObject)
{
    return (string)dependencyObject.GetValue(OriginalToolTipProperty);
}

/// <summary>
/// Provides Button controls with an additional tool tip property that only displays when the Button.IsEnabled property value is set to false.
/// </summary>
public static DependencyProperty DisabledToolTipProperty = DependencyProperty.RegisterAttached("DisabledToolTip", typeof(string), typeof(ButtonProperties), new UIPropertyMetadata(string.Empty, OnDisabledToolTipChanged));

/// <summary>
/// Gets the value of the DisabledToolTip property.
/// </summary>
/// <param name="dependencyObject">The DependencyObject to return the DisabledToolTip property value from.</param>
/// <returns>The value of the DisabledToolTip property.</returns>
public static string GetDisabledToolTip(DependencyObject dependencyObject)
{
    return (string)dependencyObject.GetValue(DisabledToolTipProperty);
}

/// <summary>
/// Sets the value of the DisabledToolTip property.
/// </summary>
/// <param name="dependencyObject">The DependencyObject to set the DisabledToolTip property value of.</param>
/// <param name="value">The value to be assigned to the DisabledToolTip property.</param>
public static void SetDisabledToolTip(DependencyObject dependencyObject, string value)
{
    dependencyObject.SetValue(DisabledToolTipProperty, value);
}

/// <summary>
/// Adds ro removes event handlers to the Button control that updates the Button.ToolTip value to the DisabledToolTip property value when the Button.IsEnabled property value is set to false.
/// </summary>
/// <param name="dependencyObject">The Button object.</param>
/// <param name="e">The DependencyPropertyChangedEventArgs object containing event specific information.</param>
public static void OnDisabledToolTipChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
    Button button = dependencyObject as Button;
    if (button != null && e.OldValue != e.NewValue) button.IsEnabledChanged += Button_IsEnabledChanged;
    else if (e.OldValue != null && e.NewValue == null) button.IsEnabledChanged -= Button_IsEnabledChanged;
}

private static void Button_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    Button button = sender as Button;
    if (GetOriginalToolTip(button) == null) button.SetValue(originalToolTipPropertyKey, button.ToolTip.ToString());
    button.ToolTip = (bool)e.NewValue ? GetOriginalToolTip(button) : GetDisabledToolTip(button);
}

次のように使用されます。

<Button ToolTip="Normal ToolTip text to display" 
    Attached:ButtonProperties.DisabledToolTip="Text to automatically display when
    Button is disabled">
于 2013-10-03T09:18:15.530 に答える
0

気になる人のために、Sheridan が共有したコードに基づいて構築された基本的なロジックを次に示します。これをもっと簡潔にすることもできますが、これにより、新しい WPF 開発者が作業を開始しやすくなります。

ツールチップとデータをサポートする任意のコントロールに使用できる xaml スタイルを次に示します。

<Style TargetType="TextBox">
<Style.Triggers>
    <Trigger Property="Validation.HasError"
                        Value="true">
        <!-- We have an error, set the ErrorToolTip attached property to
        the error.  When the error is no more, it is automatically set 
        back to the original value (blank) so no need for a 2nd trigger -->
        <Setter Property="wpfMisc:myCtrl.ErrorToolTip"
                        Value="{Binding RelativeSource={x:Static RelativeSource.Self},
      Path=(Validation.Errors)[0].ErrorContent}" />

    </Trigger>

</Style.Triggers>
</Style>

そして、依存関係のプロパティ/属性を保持するクラスに (ここでは myCtrl を使用して) 追加できるコードを次に示します。

/// <summary>
/// Holds the default Tooltip value.  OnMyToolTipChanged used to set ToolTip
/// </summary>
public static DependencyProperty MyToolTipProperty = DependencyProperty.RegisterAttached("MyToolTip", typeof(string), typeof(myCtrl), new UIPropertyMetadata(string.Empty, OnMyToolTipChanged));

/// <summary>
/// Gets the value of the MyToolTip property.
/// </summary>
/// <param name="dependencyObject">The DependencyObject to return the MyToolTip property value from.</param>
/// <returns>The value of the MyToolTip property.</returns>
public static string GetMyToolTip(DependencyObject dependencyObject)
{
    return (string)dependencyObject.GetValue(MyToolTipProperty);
}

/// <summary>
/// Sets the value of the MyToolTip property.
/// </summary>
/// <param name="dependencyObject">The DependencyObject to set the MyToolTip property value of</param>
/// <param name="value">The value to be assigned to the MyToolTip property.</param>
public static void SetMyToolTip(DependencyObject dependencyObject, string value)
{
    dependencyObject.SetValue(MyToolTipProperty, value);
}

/// <summary>
/// Initially blank, set by style when an error occures (or goes away).  Uses OnErrorToolTipChanged to update ToolTip.
/// </summary>
public static DependencyProperty ErrorToolTipProperty = DependencyProperty.RegisterAttached("ErrorToolTip", typeof(string), typeof(myCtrl), new UIPropertyMetadata(string.Empty, OnErrorToolTipChanged));

/// <summary>
/// Gets the value of the ErrorToolTip property.
/// </summary>
/// <param name="dependencyObject">The DependencyObject to return the ErrorToolTip property value from</param>
/// <returns>The value of the ErrorToolTip property.</returns>
public static string GetErrorToolTip(DependencyObject dependencyObject)
{
    return (string)dependencyObject.GetValue(ErrorToolTipProperty);
}

/// <summary>
/// Sets the value of the ErrorToolTip property.
/// </summary>
/// <param name="dependencyObject">The DependencyObject to set the  ErrorToolTip property value of</param>
/// <param name="value">The value to be assigned to the ErrorToolTip property.</param>
public static void SetErrorToolTip(DependencyObject dependencyObject, string value)
{
    dependencyObject.SetValue(ErrorToolTipProperty, value);
}

/// <summary>
/// If an Error Tooltip is supplied, sets the ToolTip to that value, otherwise, resets it back to MyToolTipProperty
/// </summary>
/// <param name="dependencyObject">The control with the tooltip</param>
/// <param name="e">The DependencyPropertyChangedEventArgs object containing event specific information.</param>
public static void OnErrorToolTipChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
    if (dependencyObject is TextBox)
    {
        var txtControl = dependencyObject as TextBox;
        if (e.NewValue == null || e.NewValue.ToString() == string.Empty)
        {
            // No tooltip, reset to the original value
            txtControl.ToolTip = (string)dependencyObject.GetValue(MyToolTipProperty);
        }
        else
        {
            // Use the error tooltip
            txtControl.ToolTip = e.NewValue;
        }
    }
}

/// <summary>
/// This should only be called when the value is first assigned to the control.
/// </summary>
/// <param name="dependencyObject">The Control</param>
/// <param name="e">The DependencyPropertyChangedEventArgs object containing event 
/// specific information.</param>
public static void OnMyToolTipChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
    // What type of control - I may be able to use a generic parent that supports Tooltips, but until I have time to figure that out, using this to generate a valid control.ToolTip reference.
    if (dependencyObject is TextBox)
    {
        var txtControl = dependencyObject as TextBox;
        if (e.OldValue != e.NewValue)
        {
            txtControl.ToolTip = e.NewValue;
        }
    }
    else if (dependencyObject is ComboBox)
    {
        // Add code here for ComboBox and other tooltip controls (if we can't use a parent/interface reference instead.)
    }
}

もちろん、スタイルなどには他にもたくさんありますが、この問題を解決するのに必要なコードだけが得られるように、すべて省略しました。

これが誰かに役立つことを願っています...

(もっとうまくやれると思うなら、それをやってみよう。アイデアが多ければ多いほど良い)

于 2013-10-04T19:01:28.997 に答える