Re: Specify ResourceDictionary and ResourceKey in Binding
Hi,
I have investigated further that issue.
I think the problem has nothing to do with the C++ API.
I've done a minimal project to reprodute the issue. Here is my code:
TestControl.xaml
I also have a RootModel, which is bound to the application root (ROOT) in C++, containing a ResourceDictionary of String (called Bank). This Bank should be bound to the TestConverter in TestControl (TestConverter turns its argument into a key to interrogate the Bank and returns the associated value). The Converter is finally used for the Text property in the TextBlock in TestControl. Finally, TestControl uses its Data Context to get the key to interrogate the Bank.
This does not work, because it seems TestConverter cannot find the Bank field in the root data context. However, if I don't set any Data Context for TestControl (and uses the Tag property to write the key for instance), it works juste fine.
My guess is that the Converter interrogate the first Data Context it finds and does not go upper in the element tree. Is that an expected behaviour?
I have investigated further that issue.
I think the problem has nothing to do with the C++ API.
I've done a minimal project to reprodute the issue. Here is my code:
Code: Select all
<Border
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="ROOT">
<Border.Resources>
<KeyModel x:Name="Model" Key="SomeKey"/>
</Border.Resources>
<StackPanel
Orientation="Vertical"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Border x:Name="PART_Slot1">
<TestControl DataContext="{StaticResource Model}"/>
</Border>
<Border x:Name="PART_Slot2"/>
</StackPanel>
</Border>
Code: Select all
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
x:Class="TestControl" x:Name="ROOT_TestControl">
<UserControl.Resources>
<TestConverter x:Name="Converter" Test="{Binding Bank}"/>
</UserControl.Resources>
<Border
BorderThickness="1"
BorderBrush="Red">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Text: "/>
<TextBlock
Text="{Binding Key, Converter={StaticResource Converter}}"/>
</StackPanel>
</Border>
</UserControl>
This does not work, because it seems TestConverter cannot find the Bank field in the root data context. However, if I don't set any Data Context for TestControl (and uses the Tag property to write the key for instance), it works juste fine.
My guess is that the Converter interrogate the first Data Context it finds and does not go upper in the element tree. Is that an expected behaviour?
-
sfernandez
Site Admin
- Posts: 3184
- Joined:
Re: Specify ResourceDictionary and ResourceKey in Binding
Yes, that is the expected behavior. When you set a binding without a explicit source, DataContext property is used. And DataContext is inherited from the first ancestor that has this property set. In your case the TestControl.DataContext="{StaticResource Model}". So the TestConverter inside that control will look for a property named Bank in the KeyModel class without success.My guess is that the Converter interrogate the first Data Context it finds and does not go upper in the element tree. Is that an expected behaviour?
You might make accessible the root DataContext through a property in the KeyModel class:
Code: Select all
public class KeyModel
{
...
public RootModel RootModel { get; set; }
}
Code: Select all
<TestConverter x:Name="Converter" Test="{Binding RootModel.Bank}"/>
Re: Specify ResourceDictionary and ResourceKey in Binding
Oh, ok, that makes sense, thank you!
Re: Specify ResourceDictionary and ResourceKey in Binding
Hi,
I still have some questions on that subject.
Now, what I'm doing is using that converter in a ControlTemplate like that:
The first time I did that, it worked perfectly (I was using it on a CustomControl deriving from Control) but now, when I try to do the exact same thing (my control is now deriving from HeaderedItemsControl), it leads to a stack overflow when I declare the ResourceConverter with that binding. I've tried to replace that line with:
That works but that's not how I want to use it.
Finally, I've tried to display the name of the VIEW_ROOT element somewhere in that ControlTemplate and it works, meaning that the element is correctly found.
I don't really know where to look from there and I can't see why it's doing that stack overflow. Also I've notices that the two same methods were called other and other again, one after the other. I don't have the debug symbol so I can't really tell you more.
I guess that's not enough information for you to find out what's going on but you may have a lead for me to investigate.
Thank you,
Alexandre.
I still have some questions on that subject.
Now, what I'm doing is using that converter in a ControlTemplate like that:
Code: Select all
<ControlTemplate TargetType="{x:Type MyControl}">
<ControlTemplate.Resources>
<ResourceConverter x:Key="LocConv" Resources="{Binding LocDictionary, ElementName=VIEW_ROOT}"/>
</ControlTemplate.Resources>
[...]
</ControlTemplate>
Code: Select all
<ResourceDictionary x:Key="MyDictionary" Source="mypath.xaml"/>
<ResourceConverter x:Key="LocConv" Resources="{StaticResource MyDictionary}"/>
Finally, I've tried to display the name of the VIEW_ROOT element somewhere in that ControlTemplate and it works, meaning that the element is correctly found.
I don't really know where to look from there and I can't see why it's doing that stack overflow. Also I've notices that the two same methods were called other and other again, one after the other. I don't have the debug symbol so I can't really tell you more.
I guess that's not enough information for you to find out what's going on but you may have a lead for me to investigate.
Thank you,
Alexandre.
-
sfernandez
Site Admin
- Posts: 3184
- Joined:
Re: Specify ResourceDictionary and ResourceKey in Binding
Could you please create a ticket and attach a crash dump for the stack overflow. We will investigate where is occurring the recursion.The first time I did that, it worked perfectly (I was using it on a CustomControl deriving from Control) but now, when I try to do the exact same thing (my control is now deriving from HeaderedItemsControl), it leads to a stack overflow when I declare the ResourceConverter with that binding.
I tried to reproduce the problem myself with the following sample without success:
Code: Select all
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyControl"
x:Name="root">
<UserControl.Resources>
<ControlTemplate x:Key="myTemplate" TargetType="MyHeaderedItemsControl">
<ControlTemplate.Resources>
<LocalizationConverter x:Key="localizationConverter"
Resources="{Binding Localization, ElementName=root}"/>
</ControlTemplate.Resources>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock Text="{Binding Id1, ElementName=root,
Converter={StaticResource localizationConverter}}"/>
<TextBlock Text="{Binding Id2, ElementName=root,
Converter={StaticResource localizationConverter}}"/>
<Button Content="Switch Language"
Command="{Binding SwitchLanguage, ElementName=root}"/>
</StackPanel>
</ControlTemplate>
</UserControl.Resources>
<MyHeaderedItemsControl Template="{StaticResource myTemplate}"/>
</UserControl>
What are you doing different from that test?
Re: Specify ResourceDictionary and ResourceKey in Binding
The only difference I can see is that I'm defining my ControlTemplate within a Style.
Now, about a crash dump, I can't do it, the XamlPlayer give me none (I get a "Gui.XamlPlayer has stopped working" and all I can do is closing the program).
Now, about a crash dump, I can't do it, the XamlPlayer give me none (I get a "Gui.XamlPlayer has stopped working" and all I can do is closing the program).
-
sfernandez
Site Admin
- Posts: 3184
- Joined:
Re: Specify ResourceDictionary and ResourceKey in Binding
Ok, I will try to reproduce it that way.The only difference I can see is that I'm defining my ControlTemplate within a Style.
Even if we cannot show a crash dialog you may be able to get one from Windows. Try the following: when the "Gui.XamlPlayer has stopped working" dialog is shown, open the Task Manager, right click on the crashing process and select 'Create Dump File'.Now, about a crash dump, I can't do it, the XamlPlayer give me none (I get a "Gui.XamlPlayer has stopped working" and all I can do is closing the program).
Who is online
Users browsing this forum: No registered users and 3 guests