Wpf样式触发器仅触发一次

时间:2017-10-10 11:53:26

标签: c# wpf

我在网格上添加了一个属性触发器,如下所示

<Grid.Style>
    <Style TargetType="{x:Type Grid}">
        <Style.Triggers>
          <Trigger Property="IsMouseOver" Value="False">
                <Setter Property="ToolTip" Value=""></Setter>
            </Trigger>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="ToolTip" Value="{Binding StoredValue}"></Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
</Grid.Style>

当我将鼠标悬停在网格上时,只触发一次该属性。 我需要的是每次MouseHover发生时都必须调用属性的(StoredValue)getter。

请帮忙

2 个答案:

答案 0 :(得分:1)

如果您确实想在每次显示时更新工具提示,可以使用ToolTipOpening事件刷新绑定:

<Grid x:Name="grid1" Background="Transparent">
    <Grid.Style>
        <Style TargetType="Grid">
            <Setter Property="ToolTip" Value="{Binding StoredValue,TargetNullValue=''}"/>
            <EventSetter Event="ToolTipOpening" Handler="grid1_ToolTipOpening"/>
        </Style>
    </Grid.Style>
</Grid>

更新后面代码中的绑定:

private void grid1_ToolTipOpening(object sender, ToolTipEventArgs e)
{
    var s = sender as FrameworkElement;
    var be = BindingOperations.GetBindingExpressionBase(s, FrameworkElement.ToolTipProperty);
    if (be != null)
    {
        be.UpdateTarget();
    }
}

注意:如果TargetNullValue=''有时会返回StoredValue,则null是必需的。否则,工具提示将不会尝试打开,因此ToolTipOpening永远不会发生,并且该值永远不会从null更新为新值。

答案 1 :(得分:-1)

虽然我无法解释问题的本质,但这是一个快速的解决方法:手动上升通知,然后绑定将刷新自己。您交易事件的触发器:

<Grid Background="Transparent" MouseEnter="Grid_MouseEnter">
    <Grid.Style>
        <Style TargetType="{x:Type Grid}">
            <!-- normal binding, this line is comment and should be gray -->
            <Setter Property="ToolTip" Value="{Binding StoredValue}" />
        </Style>
    </Grid.Style>
</Grid>


public partial class MainWindow : Window, INotifyPropertyChanged
{
    public string StoredValue => "123"; // is called every time mouse is entered

    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
    }

    public event PropertyChangedEventHandler PropertyChanged;

    // rise notification manually
    void Grid_MouseEnter(object sender, MouseEventArgs e) =>
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(StoredValue)));

}