XAML array issue - arrays

I am using the following arrays as parameters to my value converter. I can't figure why "params2" is passed as an ArrayExtension and "params1" is passed as a simple TextBlock[] array.
<Window.Resources>
<x:Array Type="TextBlock" x:Key="params1">
<TextBlock Text="{x:Static local:Constants.MyDir}"></TextBlock>
<TextBlock>25</TextBlock>
</x:Array>
</Window.Resources>
<TabItem.Resources>
<x:Array Type="TextBlock" x:Key="params2">
<TextBlock Text="{x:Static local:Constants.MyDir}"></TextBlock>
<TextBlock>55</TextBlock>
</x:Array>
</TabItem.Resources>
Image Viewer XAML:
<Window x:Class="TotalViewer.ImageViewerWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TotalViewer"
Title="ImageViewerWindow" Name="ImageViewerWindow1">
<Window.Resources>
<x:Array Type="TextBlock" x:Key="params1">
<TextBlock Text="{x:Static local:Constants.MyDir}"></TextBlock>
<TextBlock>25</TextBlock>
</x:Array>
</Window.Resources>
<Grid>
<Image Source="{Binding ElementName=ImageViewerWindow1, Path=ImagePath,
Converter={StaticResource ImageConverter},
ConverterParameter={StaticResource params1}}"/>
</Grid>
</Window>

Well, I kinda gave up for the moment because I need to get this part working. In the converter, I test if the parameter is either ArrayExtension or TextBlock[]. If it's ArrayExtension, it will get converted to TextBlock[].

Related

How to set ItemsSource in XAML?

I have set ItemsSource of a ListBox as follows :
<ListBox ItemsSource="{Binding abc}" />
What I want
<ListBox>
<listBox.ItemsSource>
?????????????
<listBox.ItemsSource>
</ListBox>
<Window xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<ListBox>
<ListBox.ItemsSource>
<x:Array Type="sys:String">
<sys:String>1st item</sys:String>
<sys:String>2nd item</sys:String>
</x:Array>
<ListBox.ItemsSource>
</ListBox>
</Window>
<ListBox>
<listBox.ItemsSource>
<Binding Path = "abs" />
<listBox.ItemsSource>
</ListBox>
Xamarin Example
If you wandered into this page looking for a Xamarin example (the question seems generic to XAML), then you can try -
<Picker x:Name="picker"
Title="Select a monkey"
TitleColor="Red">
<Picker.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Baboon</x:String>
<x:String>Capuchin Monkey</x:String>
<x:String>Blue Monkey</x:String>
<x:String>Squirrel Monkey</x:String>
<x:String>Golden Lion Tamarin</x:String>
<x:String>Howler Monkey</x:String>
<x:String>Japanese Macaque</x:String>
</x:Array>
</Picker.ItemsSource>
</Picker>
From -
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/picker/populating-itemssource#populating-a-picker-with-data
This uses Picker as an example, but the ItemsSource syntax is interchangeable based on the outer control, like so -
<ListView>
<ListView.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>mono</x:String>
<x:String>monodroid</x:String>
<x:String>monotouch</x:String>
<x:String>monorail</x:String>
<x:String>monodevelop</x:String>
<x:String>monotone</x:String>
<x:String>monopoly</x:String>
<x:String>monomodal</x:String>
<x:String>mononucleosis</x:String>
</x:Array>
</ListView.ItemsSource>
</ListView>
#HighCore, #DanPazey, and #Vishal:
In fact, the markup binding syntax may prove to be useful and even necessary.
Not to mention multibinding, consider the following.
Suppose you need to bind your ListBox to CollectionViewSource (for sorting or else). Like this:
<Window.Resources>
<CollectionViewSource x:Key="abc_CVS_Key" Source="{Binding abc}" />
</Window.Resources>
<ListBox ItemsSource="{Binding Source={StaticResource abc_CVS_Key}}">
</ListBox>
You may want then, for technical reasons, to limit a scope of the CVS resource to only the ListBox in question.
If you write down ItemsSource binding in an attribute
<ListBox ItemsSource="{Binding Source={StaticResource abc_CVS_Key}}">
<ListBox.Resources>
<CollectionViewSource x:Key="abc_CVS_Key" Source="{Binding abc}" />
</List.Resources>
</ListBox>
your code will compile, but runtime your program will not find your abc_CVS_Key resource key, because the resource has been defined later in code. You need to define the resource before you refer to it in ListBox' ItemsSource binding. Like this:
<ListBox>
<ListBox.Resources>
<CollectionViewSource x:Key="abc_CVS_Key" Source="{Binding abc}" />
</List.Resources>
<ListBox.ItemsSource>
<Binding Source="{StaticResource abc_CVS_Key}" />
</ListBox.ItemsSource>
</ListBox>
This code compiles and executes OK.

How to make binding from user control to property of parent control?

I've seen similar questions, but I still not able to do my need. I need to output checkbox's name through a label inside a user control:
Window1.xaml:
<Window x:Class="WpfBinding.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfBinding" Title="Window1" Height="300" Width="300">
<Grid>
<CheckBox Name="checkBox1">
<local:UserControl1></local:UserControl1>
</CheckBox>
</Grid>
</Window>
UserControl1.xaml:
<UserControl x:Class="WpfBinding.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Canvas>
<Label Content="{Binding ElementName=checkBox1, Path=Name}"></Label>
</Canvas>
</UserControl>
How to do it correctly? What lack of knowledge I have? Thanks for help.
Above solution will work, but a more direct solution for this specific problem would be to use RelativeSource binding in your user control as below:
<Canvas>
<Label Content="{Binding RelativeSource={RelativeSource AncestorType=CheckBox, AncestorLevel=1}, Path=Name}"></Label>
</Canvas>
Hope this is what you need !!!
ElementName binding works within in same XAML scope. This will work -
<Grid>
<CheckBox Name="checkBox1"/>
<Label Content="{Binding ElementName=checkBox1, Path=Name}"/>
</Grid>
But if you want to do it in different UserControl, you have to tweak a bit your code and use Tag to hold name -
<Grid>
<CheckBox Name="checkBox1">
<local:UserControl1 Tag="{Binding ElementName=checkBox1, Path=Name}"/>
</CheckBox>
</Grid>
UserControl.xaml
<Canvas>
<Label Content="{Binding Path=Tag, RelativeSource={RelativeSource
Mode=FindAncestor, AncestorType=UserControl}}"/>
</Canvas>
On a sidenote, in your UserControl, you know you need to bind with ElementName = checkBox1 and that's the name only you are binding to. Its something equivalent to -
<Label Content="checkBox1"/>

CompositeCollection breaks ComboBox AutoComplete-Feature?

push
Hello everybody!
I'm using a WPF ComboBox with IsTextSearchEnabled="True" (Autocomplete) and want to bind its ItemsSource-Property to a CompositeCollection. Unfortunately, the Combobox doesn't seem to recognize the items provided by a CollectionContainer within the CompositeCollection. They are shown, but not selected by AutoComplete.
Please try the example, type in "def". If "def" doesn't get selected, you've reproduced the problem I'm facing. Is there any solution, something that I've overseen or a practical way to work around while having some mergedcollection-capability?
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<XmlDataProvider x:Key="XData1" XPath="/Info">
<x:XData>
<Info xmlns="">
<Item>def</Item>
<Item>efg</Item>
</Info>
</x:XData>
</XmlDataProvider>
<CollectionViewSource x:Key='Data1' Source="{Binding Source={StaticResource XData1}, XPath=Item}" />
</Window.Resources>
<Grid>
<ComboBox IsEditable="True" IsTextSearchEnabled="True" Margin="0,0,0,283">
<ComboBox.ItemsSource>
<CompositeCollection>
<ComboBoxItem>abc</ComboBoxItem>
<ComboBoxItem>bcd</ComboBoxItem>
<ComboBoxItem>cde</ComboBoxItem>
<CollectionContainer Collection="{Binding Source={StaticResource Data1}}" />
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>
</Grid>
Thanks!
- dartrax
I've found out that this is solved as soon as you override the ToString()-Function of your Items-object, so that it returns what the items DataTemplate shows.
A complete working example is here:
--------> X
dartrax

Binding to a data template control property

Is it possible to bind something to a property of a control in a data template entirely in XAML? The following code is a simplified version of the problem I'm running into. I'd like the text of the TextBlock (displayName) to be updated as the user types in the TextBox located in the DataTemplate.
<Window x:Class="WpfApplication4.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WpfApplication4="clr-namespace:WpfApplication4"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<DataTemplate DataType="{x:Type WpfApplication4:Foo}">
<TextBox Text="{Binding Path=Name}" />
</DataTemplate>
<WpfApplication4:Foo x:Key="testObject" Name="This is a test" />
</Window.Resources>
<StackPanel>
<TextBlock x:Name="displayName" Margin="5" />
<ContentControl x:Name="contentControl" Margin="5" Content="{StaticResource testObject}" />
</StackPanel>
No, at least, not from XAML. You could write code to traverse the visual tree and find the element you want to bind to, but that would be nasty.
But in your particular example, would it not make sense to just bind the TextBlock to the same data object (Foo instance)?

Exception thrown when resources declaration order changed

I get exception when declare resources in this order:
<Window.Resources>
<sys:Object x:Key="resourceA"></sys:Object>
<x:Array x:Key="resourceB" Type="sys:String">
<sys:String>foo</sys:String>
</x:Array>
</Window.Resources>
and when declare this way, all works:
<Window.Resources>
<x:Array x:Key="resourceB" Type="sys:String">
<sys:String>foo</sys:String>
</x:Array>
<sys:Object x:Key="resourceA"></sys:Object>
</Window.Resources>
The Exception thrown is:
Cannot convert the value in attribute
'ItemsSource' to object of type
'System.Collections.IEnumerable'.
'System.Windows.Markup.ArrayExtension'
is not a valid value for property
'ItemsSource'. Error at object
'System.Windows.Controls.ComboBox' in
markup file
'WpfResourcesBug;component/window1.xaml'
Line 18 Position 37.
Full code:
<Window x:Class="WpfResourcesBug.Window1"
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"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<sys:Object x:Key="resourceA"></sys:Object>
<x:Array x:Key="resourceB" Type="sys:String">
<sys:String>foo</sys:String>
</x:Array>
</Window.Resources>
<StackPanel>
<ComboBox SelectedIndex="0" ItemsSource="{StaticResource resourceB}" />
</StackPanel>
</Window>
I think you might find a possible solution here

Resources