Search code examples
c#wpf

WPF tooltip Binding getting override when I set the tooltip from code


I have a User control and I bind the tooltip of that control into some object's property

                        <usercontrols:ucButton x:Name="xSaveCurrentBtn" ButtonType="ImageButton" ButtonFontImageSize="16" ButtonImageWidth="18" ButtonImageHeight="18" ButtonImageType="Save" Click="xSaveSelectedButton_Click" ButtonStyle="{StaticResource $ImageButtonStyle_Menu}" DockPanel.Dock="Right" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,0,0">
                            <usercontrols:ucButton.ToolTip>
                                <ToolTip Content="{Binding ItemName, Mode=OneWay}" ContentStringFormat="Save {0}"/>
                            </usercontrols:ucButton.ToolTip>
                        </usercontrols:ucButton>

from the code I set the data context of the ucButton to be my object:

xSaveCurrentBtn.DataContext = WorkSpace.Instance.CurrentSelectedItem;

sometimes the CurrentSelectedItem is null, and if this is the case I want the tooltip to display "No Item Selected" I tried doing this:

xSaveCurrentBtn.Tooltip = "No Item Selected";

but when the CurrentSelectedItem isn't null and I reset the xSaveBtn.DataContext to that object, I am still seeing the No Item Selected tooltip as if my WPF tooltip section was overriden and its no longer binding into the datacontext ItemName Property


Solution

  • You are trying to set a property to two values at the same time. It's impossible. What you are doing in XAML is equivalent to:

        xSaveCurrentBtn.Tooltip = new ToolTip() {.....};
    

    When you setting a string value to the same property, the previous value is lost. And it is not possible to restore it if you do not save it first.

    You might want to assign a value in case of a binding error:

    <ToolTip Content="{Binding ItemName,
                               Mode=OneWay,
                               FallbackValue='No Item Selected'}"
             ContentStringFormat="Save {0}"/>
    

    how can I bind the data context to update to be the new CurrentSelectedItem without explicitly setting it?

    Assuming that «WorkSpace.Instance» is an immutable property that returns an instance of «WorkSpace» and «CurrentSelectedItem» is a property with an «INotifyPropertyChanged.PropertyChanged» notification, then you can do this:

    <usercontrols:ucButton DataContext="{Binding CurrentSelectedItem, Source={x:Static viewmodels:WorkSpace.Instance}}" ...>
    

    The «viewmodels» prefix depends on the assembly and namespace in which the «WorkSpace» class is declared.