Bind to other element in a stackpanel without name - wpf

I'm creating a DataTemplate in WPF, so it won't compile if I use x:Name. This is the relevant part of my code:
<DataTemplate>
<StackPanel>
<Image .../>
<Textbox Width={Binding to image?, Path=ActualWidth} />
</StackPanel>
</DataTemplate>
How can I bind to the Image without the use of name?

You can use RelativeSource:
<DataTemplate>
<StackPanel>
<Image Source="{Binding Photo}"/>
<TextBox Width="{Binding Path=Children[0].ActualWidth, Mode=OneWay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=StackPanel, AncestorLevel=1}}" />
</StackPanel>
</DataTemplate>
You can't directly binding to Image but you can do that with StackPanel and property Children.

Related

How to use converters without binding paths?

I have a Combobox whose ItemsSource is an ObservableCollection of int values.
My combobox itemtemplate consists on an image and a textblock which content is given by 2 converters.
How can I set this 2 bindings? The following code does not compile:
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding, Converter={StaticResource IntToImageConverter}}" Stretch="None" />
<TextBlock Text="{Binding, Converter={StaticResource IntToStringConverter}}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
You need to remove the , so:
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Converter={StaticResource IntToImageConverter}}" Stretch="None" />
<TextBlock Text="{Binding Converter={StaticResource IntToStringConverter}}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>

Binding to viewmodel's property from a template

I made a view for my GameViewModel
I have some xaml like that
<UserControl.Resources>
<DataTemplate DataType="{x:Type ViewModels:PlayerViewModel}">
<StackPanel>
<Button
Content="{Binding ?????}"
Command="{Binding WrongAnswerCommand}" />
<TextBlock
Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<ListBox Grid.Row="0"
ItemsSource="{Binding Players}"
IsSynchronizedWithCurrentItem="True">
</ListBox>
</Grid>
So, here it is an observable collection Players.
I need the button content to be binded to GameViewModel's property.
What should I use?
Basically, you need to go up to a higher level to get the full view model.
Something like
Content="{Binding DataContext.MyContentPropertyName,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ListBox}}}"
Or
Content="{Binding DataContext.MyContentPropertyName,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type UserControl}}}"
Where MyContentPropertyName is the property in GameViewModel that represents the content of the button.
Note: from the snippet it seems that both bindings will produce the same result, adding them both to make an example that you can choose how high you want to go to find the right context.

Silverlight pass DataContext to ConverterParameter?

How can I pass the DataContext of LayoutRoot to the converter of the ContentControl inside the ListBox items template?
<Grid x:Name="LayoutRoot"
Background="White"
DataContext="{Binding Source={StaticResource myViewModel}}">
<StackPanel HorizontalAlignment="Left"
Margin="6,6,0,394"
Orientation="Vertical"
Width="200"
d:LayoutOverrides="Height">
<ListBox x:Name="listBox2"
ItemsSource="{Binding MyCollection, Mode=TwoWay}"
VerticalAlignment="Top"
Height="400">
<ListBox.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}"
ContentTemplate="{Binding Converter={StaticResource myConverter}}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBox Text="{Binding Value1, Mode=TwoWay}"/>
</StackPanel>
</Grid>
I want to be able to touch the objects inside the DataContext from within the Converter and use them for TwoWay binding on controls within the ListBox item's DataTemplate.
Any ideas? Any suggestions?
Thank you.
I just got the DataContext up to the converter using:
<ContentControl Content="{Binding}"
ContentTemplate="{Binding Converter={StaticResource stringToDataTemplateConverter}, ConverterParameter={StaticResource myViewModel}}" />
Now I have another problem my dynamic property binding is not working.
(sorry for my bad english)
I'm not sure about what you are trying to do here but with SL 5 you can use RelativeSource to get the DataContext:
{Binding DataContext,RelativeSource={RelativeSource AncestorLevel=1,AncestorType=Grid}}

WPF ListBox ItemTemplate: How to make contents fill available space?

I have set my ListBox.ItemTemplate to something like below
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="10">
<TextBlock Text="{Binding Args}" />
<ProgressBar Value="{Binding Progress}" Height="10" />
<TextBlock Text="{Binding Status}" />
<TextBlock Text="{Binding Result}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
The result is
How can I make the StackPanel fill the entire width of the ListBox?
Off the top of my head, Set the HorizontalContentAlignment property of the Listbox to Stretch.

WPF : InputBindings on a StackPanel

I want to put a command on a ListBoxItem. The ListBoxItem use a DataTemplate composed of a StackPanel (containing an Image and a TextBlock, both using Binding). I want that the doubleclick on that ListBoxItem fire the command.
I have tried this :
<DataTemplate>
<StackPanel>
<StackPanel.Resources>
<CommonUI:CommandReference x:Key="DoubleClickCommand" Command="{Binding Path=DefaultCommand}" />
</StackPanel.Resources>
<StackPanel.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{StaticResource DoubleClickCommand}" />
</StackPanel.InputBindings>
<Image Source="{Binding Path=Thumbnail, IsAsync=True}" IsHitTestVisible="False"/>
<TextBlock Text="{Binding Path=Name}" IsHitTestVisible="False">
</StackPanel>
</DataTemplate>
I have also tried to put the Command Resources on a StackPanel containing this StackPanel, without any change.
I am certain of my binding because when I put the InputBindings part on the TextBlock, it works.
Thanks
Try handling the event in the ListBox instead of the StackPanel:
<ListBox>
<ListBox.Resources>
<CommonUI:CommandReference x:Key="DoubleClickCommand" Command="{Binding Path=DefaultCommand}" />
</ListBox.Resources>
<ListBox.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{StaticResource DoubleClickCommand}" />
</ListBox.InputBindings>
<DataTemplate>
<StackPanel>
<Image Source="{Binding Path=Thumbnail, IsAsync=True}" />
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
</ListBox>
My code finally looks like this :
<DataTemplate>
<StackPanel Orientation="Vertical">
<StackPanel.Resources>
<CommonUI:CommandReference x:Key="DoubleClickCommand" Command="{Binding Path=DefaultCommand}" />
</StackPanel.Resources>
<StackPanel.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{StaticResource DoubleClickCommand}" />
</StackPanel.InputBindings>
<Image Source="{Binding Path=Thumbnail, IsAsync=True}" />
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
Thanks anyway, Mr Poulin.

Resources