Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force binding in WPF

I'm writing tests which will check correctness of Binding elements specified in XAML. They work so far, the only issue is that I do not know how to correctly force databinding to happen. Surprisingly it is not enough to simply set something in DataContext, binding won't happen until you show your control/window. Please not that I'm writing 'unit'-tests and I'd like to avoid showing any windows.

Take a look at following code:

// This is main class in console application where I have all WPF references added
public class Program
{
    [STAThread]
    public static void Main()
    {
        var view = new Window();
        BindingOperations.SetBinding(view, Window.TitleProperty, new Binding("Length"));
        view.DataContext = new int[5];
        //view.Show(); view.Close(); // <-- this is the code I'm trying not to write
        Console.WriteLine(view.Title);
    }
}

Here I'm creating a Window and putting an array as DataContext to that window. I'm binding Window.Title to Array.Length so I expect to see number 5 printed in console. But until I Show window (commented line) I will get empty string. If I uncomment that line then I will receive desired 5 in console output.

Is there any way I can make binding happen without showing a window? It is pretty annoying to look at ~20 windows while launching tests.

P.S.: I know I can make windows more transparent and etc, but I'm looking for more elegant solution.

UPDATE Code above is simplified version of what I really have. In real code I receive a View (some UIElement with bindings) and object ViewModel. I do not know which exactly binding there were set on View, but I still want all of them to be initialized.

UPDATE 2: Answering to the questions regarding what I test and I why. I do not intend to test that classes like Binding, BindingBase, etc are working as expected, I assume they are working. I'm trying to test that in all my XAML files I have written bindings correctly. Because bindings are stringly typed things, they are not verified during compilation and by default they cause only errors in output window, which I'm missing occasionally. So if we take my example from above and if we will made a typo there in binding: {Binding Lengthhh} then my tests will notify you that there is no property with name Lengthhh available for binding. So I have around 100 XAML files and for each XAML I have a test (3-5 lines of code) and after launching my tests I know for sure that there are no binding errors in my solution.

like image 721
Snowbear Avatar asked Mar 22 '11 19:03

Snowbear


1 Answers

The bindings are updated by the dispatcher with the DispatcherPriority.DataBind - so if you wait for a dummy task with SystemIdle priority you are sure that any pending databinding is done.

  try
  {
    this.Dispatcher.Invoke(DispatcherPriority.SystemIdle, new Action(() => { }));
  }
  catch
  {
    // Cannot perfom this while Dispatcher in suspended mode
  }
like image 172
Hans Karlsen Avatar answered Oct 08 '22 15:10

Hans Karlsen