Using UIModel Class For Binding In WPF — Digitteck
Using UIModel Class For Binding In WPF
dotnet·2 February 2018·2 min read

Using UIModel Class For Binding In WPF

Description

When creating WPF applications, you use binding. It's a very nice workflow except for one point, where I want to bind the ContentProperty of a Label or a TextBlock. If I set this up in the XAML code with {Binding}, then I don't have the "feeling" of the designer since there is no text until it compiles.

You can use SetBinding method for this programmatically in code, and having this in mind I decided that I need a UIModel class that encapsulates the logic of it.

Solution

First create a class that stores the UI Element, the dependency property whose property will be set and the property info of the UIElement that is set as a property in child class.

csharp
public class UIControledElement
  {
      //ui element from the window
      public FrameworkElement Element { get; set; }
      //dependency property to affect. Set in the attribute in the class
      public DependencyProperty LanguageProperty { get; set; }
      //property info
      public PropertyInfo UiModelProperty { get; set; }
  }

Create a base class that will act as a template for other classes. It will provide a Register method that will create UIControledElements based on the properties described in Register function.

csharp
public class UIModel where TWindow : Window
    {
        //I need the context which is the MainWindow to get the tagged properties
        private static TWindow context;
        //Because the register method below is static, this element is also static
        private static List UIControledElements = new List();

        public UIModel(TWindow context)
        {
            UIModel.context = context;
            UIModel.context.ContentRendered += Context_ContentRendered;
        }
        //Making sure that all elements are loaded and rendered, afterwards we make the changes required
        private void Context_ContentRendered(object sender, EventArgs e)
        {
            this.UpdateDisplay();
        }
        //this method is called in the child class to register a property. Because at this point the object doesn't exist
        //we need to call it statically. In here we also store the DependencyProperty that we will alter
        protected static UIControledElement Register(string PropertyInfo, DependencyProperty Property, Type Owner) {
            var propertyInfo = Owner.GetProperty(PropertyInfo, BindingFlags.Public | BindingFlags.Instance);
            if (propertyInfo != null) {
                 var uicontroled = new UIControledElement { UiModelProperty = propertyInfo, LanguageProperty = Property };
                 UIModel.UIControledElements.Add(uicontroled);
                 return uicontroled;
            }
            return null;
        }
        //this method returns the UIElement
        protected FrameworkElement GetValue(UIControledElement Element)
             { return Element.Element; }
        //this methods sets the UIElement
        protected void SetValue(UIControledElement Element, FrameworkElement Value)
            {Element.Element = Value;}

        //in this method we get the value from the attribute and call the function SetProperty
        private void UpdateDisplay()
        {
            foreach (var item in UIModel.UIControledElements)
            {
               DisplayAttribute Attribute =
               item.UiModelProperty.GetCustomAttribute(typeof(DisplayAttribute)) as DisplayAttribute;

                if (Attribute == null) return;

                SetProperty(item.Element, item.LanguageProperty, Attribute.Name);
            }
        }

        //this method alters the DependencyProperty of the UIElement with the value from an attribute
        private void SetProperty(FrameworkElement Element, DependencyProperty Property, object value) {
            Type depencendyObjectType = typeof(DependencyObject);

            MethodInfo SetValueMethodInfo =
                depencendyObjectType.GetMethod("SetValue",new Type[] { typeof(DependencyProperty), typeof(object) });
                SetValueMethodInfo.Invoke(Element, new object[] { Property, value });
        }
    }

Usage

We create a child class. UIControledElements references the element ExampleText.

csharp
public class UINumberModel: UIModel < MainWindow >
  {
    private static UIControledElement exampleText = Register("ExampleText", Label.ContentProperty, typeof(UINumberModel));
    [Display(Name = "NewLabelContent")]
    public FrameworkElement ExampleText {
        get => GetValue(exampleText);
        set => SetValue(exampleText, value);
    }
    public UINumberModel(MainWindow context): base(context) {}
}

In main you will create a new instance of this class. At initializing the base class will search for UIControledElements. It will detect that the property "ExampleText" was stored and it will change the Label.ContentProperty with the value provided in DisplayAttribute.

csharp
public MainWindow()
        {
            InitializeComponent();
            UINumberModel m = new UINumberModel(this) { ExampleText = LabelIO };
        }

Tags

C#WPF
digitteck

© 2026 Digitteck