Alex141 / CalcBinding

Advanced WPF Binding which supports expressions in Path property and other features

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Bug report: Binding Error w Bool-To-Visibility & Template DataType

metal450 opened this issue · comments

commented

I've come across what appears to be a bug when using multibindings with bool-to-visibility, where it reports binding errors for templates that shouldn't be applying (based on DataType). Here's code to repro:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication1"
    xmlns:c="clr-namespace:CalcBinding;assembly=CalcBinding"
    Title="MainWindow" Height="350" Width="525">
<StackPanel>
    
    <ContentControl x:Name="contentControl" Content="{Binding}">
        <ContentControl.Resources>
            
            <DataTemplate DataType="{x:Type local:ClassSimple}">
                <TextBlock>I am ClassSimple</TextBlock>
            </DataTemplate>

            <DataTemplate DataType="{x:Type local:ClassComplex}">
                <GroupBox>
                    <TextBlock>I am ClassComplex: <TextBlock Visibility="{c:Binding 'SomeProperty || SomeProperty2'}" /></TextBlock>
                </GroupBox>
            </DataTemplate>
            
        </ContentControl.Resources>
    </ContentControl>

    <Button Content="ClassSimple" Click="Click_ClassSimple"/>
    <Button Content="ClassComplex" Click="Click_ClassComplex"/>
</StackPanel>    
</Window>

And in CodeBehind:

public class ClassSimple { }
public class ClassComplex { public bool SomeProperty { get; set; } public bool SomeProperty2 { get; set; } }

private void Click_ClassSimple(object sender, RoutedEventArgs e)
{
    contentControl.DataContext = new ClassSimple();
}

private void Click_ClassComplex(object sender, RoutedEventArgs e)
{
    contentControl.DataContext = new ClassComplex();
}

If you click "ClassSimple," all is as expected. But if you click "ClassComplex" then "ClassSimple," you'll get:

Binding error: one of source fields is Unset, return null
System.Windows.Data Error: 5 : Value produced by BindingExpression is not valid for target property.; Value='<null>' MultiBindingExpression:target element is 'TextBlock' (Name=''); target property is 'Visibility' (type 'Visibility')

Oddly, if you remove the GroupBox in the ClassComplex template, the binding error goes away. Likewise, it goes away if you just bind to SomeProperty or SomeProperty2 (not both).

Thank you for detailed description, I will see it soon

I have analyzed this problem. It looks like a strange WPF behaviour or WPF bug. It occured only when using MultiBinding and outer container in DataTemplate. The point is that when you change DataContext of ContentPresenter, two bindings (instead of one) are updated: for previous DataTemplate (strange) and for new DataTemplate. Old MultiBinding is updated with DependencyProperty.Unset values for all pathes.

However, I note that this error should not adversely affect on system, isn't it? I have an idea to make a small correction and add support of FallbackValue, for such cases, so after that correction message in outout window will not appear

commented

I note that this error should not adversely affect on system, isn't it?

Yup the behavior does appear as it should. The problem is just that in the real application, there are a large number of such bindings, so whenever you perform an action that causes this to happen (i.e. switching tabs in a tabbed interface), the app grinds to a halt while the Output Pane catches up with the output - & actual log messages used for debugging get lost among the pages of errors. So yeah, just something to get rid of the error messages would be awesome :) 👍

Ok, I understand you :) I'll do it as soon as available time

commented

Awesome, looking forward to it! :)

commented

Just wanted to check in if you ever had a chance to look at this...?

I'm so sorry, I just forgot that I wanted to solve this issue in next iteration in 2017 :(
Good, that you remind about it :)
I include this issue in current iteration

commented

Just out of curiosity: is there any easy workaround I might be able to use in the interim? I recently had to change a core part of my application to use DataType-based templates, and the result is so many of these debug messages that it actually locks up VS when performing certain actions (i.e. changing doc tabs, which re-binds all the tool controls & prints errors for almost all of them). The application does function - it just gets so bogged down by all the logging that it's become extremely difficult to debug :/

Thanks for any thoughts :)

I'm afraid you can only disable all tracing, it will turn off messages from calcBinding lib also:

System.Diagnostics.Trace.Listeners.Clear()

But all traces from your application will be turned off also :)

You can disable only wpf binding messages, so first of two messages will stop appearing in the output window:

Binding error: one of source fields is Unset, return null

Tools->Options->Debugging->Output Window -> WPF Trace Settings -> Data binding - off

but as I understand, you have huge of messages and probably it will not help much

I'm working on normal solution 👍

commented

Sorry, but no solutions :(
I will try to release the update quicker

version 2.5.2 is released, nuget package - https://www.nuget.org/packages/CalcBinding/2.5.2

Check please that traces from calcBinding don't appear in output, and if everyting ok I close issue :)

commented

Woo hoo, looks like that did it! Safe to close - thanks so much for the quick turnaround :)