wpfbinding

WPF and binding ToolTip to a DisplayAttribute


In my view model, I have added DisplayAttributes to my properties, and would now like to bind the ToolTip property of my TextBox controls to the Description property of the DisplayAttribute.

I found this SO question which handles the reading of the description, but can't figure out how to populate the ToolTip using the calculated description.


Solution

  • This seems like a roundabout way to do this since WPF doesn't support this attribute and so you'll be entering the attributes into the view-model and the view-model will be looking them up. They could be in any internal format.

    In any case, here is a demo of the problem as you've stated it. We add a Descriptions property to the class that the text boxes are bound to. That property is a dictionary that maps property names to descriptions, that is, attributes. In the static constructor for the view-model we look up all the attributes and populate the dictionary.

    A small XAML file with two text boxes:

    <Grid >
        <StackPanel>
            <TextBox Text="{Binding FirstName}" ToolTip="{Binding Descriptions[FirstName]}"/>
            <TextBox Text="{Binding LastName}" ToolTip="{Binding Descriptions[LastName]}"/>
        </StackPanel>
    </Grid>
    

    the code-behind:

            DataContext = new DisplayViewModel();
    

    and a rudimentary view-model with two properties:

    public class DisplayViewModel
    {
        private static Dictionary<string, string> descriptions;
    
        static DisplayViewModel()
        {
            descriptions = new Dictionary<string,string>();
            foreach (var propertyName in PropertyNames)
            {
                var property = typeof(DisplayViewModel).GetProperty(propertyName);
                var displayAttributes = property.GetCustomAttributes(typeof(DisplayAttribute), true);
                var displayAttribute = displayAttributes.First() as DisplayAttribute;
                var description = displayAttribute.Name;
                descriptions.Add(propertyName, description);
            }
        }
    
        public DisplayViewModel()
        {
            FirstName = "Bill";
            LastName = "Smith";
        }
    
        public static IEnumerable<string> PropertyNames { get { return new[] { "FirstName", "LastName" }; } }
    
        [Display(Name = "First Name")]
        public string FirstName { get; set; }
    
        [Display(Name = "Last Name")]
        public string LastName { get; set; }
    
        public IDictionary<string, string> Descriptions { get { return descriptions; } }
    }