How can I bind radiobutton's checked property inside DataTemplate? - silverlight

This is my DataTemplate:
<DataTemplate x:Key="DataTemplateThemes">
<Grid Width="160" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="5,0">
<Grid.RowDefinitions>
<RowDefinition Height="28.3336664835612"/>
<RowDefinition Height="161"/>
<RowDefinition Height="Auto" />
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock x:Name="tbThemeName" HorizontalAlignment="Left" Margin="2" Grid.Row="2" TextWrapping="Wrap"
Text="{Binding ThemeName}" FontSize="16" FontFamily="Segoe UI" d:LayoutOverrides="Height"/>
<Image Margin="0" Stretch="Fill" Grid.Row="1" Source="{Binding Path=ThemePicName, Converter={StaticResource imageConverter}}"/>
<TextBlock x:Name="tbDescription" HorizontalAlignment="Left" Margin="2" Grid.Row="3"
TextWrapping="Wrap" Text="{Binding ThemeDescription}" FontSize="14.667" FontFamily="Segoe UI"
d:LayoutOverrides="Height"/>
<RadioButton Content="Apply" Margin="-10,0,0,0"
d:LayoutOverrides="Width, Height" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
The IsChecked property of RadioButton depends on Theme property which is available in my ViewModel. Initially I thought I will create a Converter that will pass the current row (datatemplate current DataContext)'s ThemeId and ViewModel's Theme (which is the selected Theme)'s ThemeId property and if they both match I would check the radiobutton. But ConverterParameter cannot take Binding expression as it is not a DependencyProperty. So how do I solve this issue?
Thanks in advance :)

You could implement a multi binding solution. I have previously implemented the solution described here:
http://www.scottlogic.co.uk/blog/colin/2010/05/silverlight-multibinding-solution-for-silverlight-4/
You could then have a converter that accepts the two required parameters.

Related

Bind to single object in viewmodel

I got this property in my viewmodel:
private PushPinModel selectedPushPinModel;
public PushPinModel SelectedPushPinModel
{
get { return selectedPushPinModel; }
set
{
selectedPushPinModel = value;
RaisePropertyChanged(() => SelectedPushPinModel);
}
}
And I want to bind the view to show which one is selected:
<ContentControl DataContext="{Binding SelectedPushPinModel}" VerticalAlignment="Top">
<ContentControl.ContentTemplate>
<DataTemplate>
<Grid Height="100" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="20*"/>
<RowDefinition Height="38*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="91*"/>
<ColumnDefinition Width="389*"/>
</Grid.ColumnDefinitions>
<Border Opacity="0.95" Width="480" Padding="0,0,0,0" BorderThickness="0" HorizontalAlignment="Left" BorderBrush="Transparent" Background="White" Grid.ColumnSpan="2" Grid.RowSpan="2"/>
<Image Width="70" Height="70" HorizontalAlignment="Center" VerticalAlignment="Center" Source="{Binding Icon}" Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" />
<TextBlock Text="{Binding Header}" Grid.Column="1" Grid.Row="0" Style="{StaticResource TextboxLabelStyle}"/>
<TextBlock Text="{Binding Body}" Grid.Column="1" Grid.Row="1" Style="{StaticResource DefaultTextBlockStyle}"/>
</Grid>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl >
However I can't get it to work. The bindings is not showing in the view and I'm not getting any binding errors. Is it the correct way to bind to a single object?
I much rather having it like this instead of binding directly with {Binding SelectedPushPinModel.Body} which more dirty.
Any suggestions how to accomplish this?
Thanks
Try this:
<Label Content="{Binding SelectedPushPinModel}" />
See what that gives you (if anything). Also, check the 'output' window for errors.
This line:
<ContentControl DataContext="{Binding SelectedPushPinModel}">
will only work if the DataContext for the ViewModel (Class) has been properly bound higher on the page. If it isn't then the Label binding provided above will show blank.
Solved it, replaced DataContext on the ContentControl with Content
<ContentControl Content="{Binding SelectedPushPinModel}" VerticalAlignment="Top">
Thanks to sircodesalot for pointing me to the right direction!

Can't stretch a control in a stackpanel

Here is a piece of my control code:
<telerik:RadWindow>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="20"/>
<RowDefinition Height="*"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="2" HorizontalAlignment="Stretch" Background="Blue">
<Grid
x:Name="DetailsGrid">
<prismvm:DataTemplateSelector
Content="{Binding NewTemplate}">
<prismvm:DataTemplateSelector.Resources>
<DataTemplate
x:Key="EmailMessageTemplate">
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch" Background="Red">
<TextBlock Text="Name: "/>
<TextBox Text="{Binding Name,Mode=TwoWay}" HorizontalAlignment="Stretch" Background="Green"/>
<TextBlock Text="Subject: "/>
<TextBox Text="{Binding EmailSubject,Mode=TwoWay}" HorizontalAlignment="Stretch"/>
<TextBlock Text="Body: "/>
<TextBox Text="{Binding Body,Mode=TwoWay}" TextWrapping="Wrap"/>
</StackPanel>
</DataTemplate>
<DataTemplate
x:Key="SmsMessageTemplate">
<StackPanel Orientation="Vertical">
<TextBlock Text="Subject: "/>
<TextBox Text="{Binding Name,Mode=TwoWay}"/>
<TextBlock Text="Sms body: "/>
<TextBox Text="{Binding Body,Mode=TwoWay}"/>
</StackPanel>
</DataTemplate>
</prismvm:DataTemplateSelector.Resources>
</prismvm:DataTemplateSelector>
</Grid>
</StackPanel>
</telerik:RadWindow>
The problem is that at start the width of the textboxes is very little and I need to have width the same as grid.
How can I do it?
EDIT
I've updated my xaml, and now every element looks like at the picture:
I've added
HorizontalContentAlignment="Stretch"
to
<prismvm:DataTemplateSelector
Content="{Binding NewTemplate}">
and now it works fine.
A StackPanel does not stretch to fit its parent container by default (in this case column 0 of the Grid, or rather the entire grid).
Try this on the outer StackPanel:
<StackPanel Grid.Row="2" HorizontalAlignment="Stretch">
Then the child TextBoxes have something to stretch to.
When in doubt, set different background colours on your various containers so you can see how much room they take up at runtime.

Making a WPF TextBox be only as wide as the room it has but expand when the space expands?

Notice how the textbox expands to the right until it has enough horizontal space to fit the content? Well I'd like it to not expand and fit the text with the space it has in the window.
If the windows expands, then the Grid.Column it's in will expand, but the textbox itself should expand to fit. Simple enough?
Any suggestions? This is my first foray into WPF and so far it's been pretty sleek.
Edit: Here's my XAML markup:
<Window x:Class="GameLenseWpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="450" Width="350" MinHeight="450" MinWidth="350">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.15*" />
<RowDefinition />
</Grid.RowDefinitions>
<Image Grid.Row="0" Stretch="Fill" Source="Image/topBarBg.png" />
<StackPanel Orientation="Horizontal" Grid.Row="0">
<TextBlock Text="Platform"
Foreground="White"
FontFamily="Georgia"
FontSize="15"
Margin="10"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
<ComboBox x:Name="cmbPlatform"
Margin="10"
FontFamily="Georgia"
FontSize="15"
MinHeight="30"
MinWidth="140"
VerticalAlignment="Center"
VerticalContentAlignment="Center" SelectionChanged="cmbPlatform_SelectionChanged">
<ComboBoxItem>All Platforms</ComboBoxItem>
<ComboBoxItem>Playstation 3</ComboBoxItem>
<ComboBoxItem>XBox 360</ComboBoxItem>
<ComboBoxItem>Wii</ComboBoxItem>
<ComboBoxItem>PSP</ComboBoxItem>
<ComboBoxItem>DS</ComboBoxItem>
</ComboBox>
</StackPanel>
<Image x:Name="imgAbout" Grid.Row="0" Source="Image/about.png"
Height="16" HorizontalAlignment="Right"
VerticalAlignment="Center"
Margin="0 0 10 0" />
<ListBox Grid.Row="1" x:Name="lstGames" Background="#343434" Padding="5">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Height="120" Margin="0 10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="90"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Border BorderBrush="#202020" BorderThickness="5" CornerRadius="4" Panel.ZIndex="0">
<Image Grid.Row="0" Grid.Column="0" Source="{Binding ImageUrl}" Stretch="Fill"/>
</Border>
<StackPanel Grid.Row="0" Grid.Column="1" Margin="12 0 0 0">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Title:" FontFamily="Arial" Foreground="White"/>
<TextBlock Text="{Binding Title}" FontFamily="Arial" Foreground="White" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Release Date:" FontFamily="Arial" Foreground="White" />
<TextBlock Text="{Binding ReleaseDate}" FontFamily="Arial" Foreground="White" />
</StackPanel>
<TextBlock Text="Synopsis" FontFamily="Arial" Foreground="White" />
<TextBox Background="#454545" Text="{Binding Synopsis}" MinHeight="76" />
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Window>
To get a TextBox to wrap inside a ListBox you can make the following changes:
Set the content of the listbox equal to the width of the listbox using: HorizontalContentAlignment="Stretch".
Disable the horizontal scrollbar of the listbox to prevent listbox from getting the desired size of the controls and preventing the word wrap in your textbox.
Set TextWrapping="Wrap" in the TextBox
Here is the XAML:
<ListBox Grid.Row="1" x:Name="lstGames" Background="#343434" Padding="5"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
HorizontalContentAlignment="Stretch" >
</ListBox>
<TextBox Text="{Binding Synopsis}" MinHeight="76" TextWrapping="Wrap" />
I believe you need to set the Margin property of your textbox control. In the designer, you can see little circles around each textbox (and each control when you focus them, for that matter). Click the little circle on the right side of the textbox, to make that control grow marginally with the available space in the current layout control (by clicking the circle, the margin will be added into the XAML).
I don't know if in your image you've already adjusted the window size, but with that image it appears you'll also need to set the width for your textbox.
Does this help?

Silverlight/WP7: I want to place an Button after the Listbox element which are data bound

I am fairly new to silverlight. I am developing on the windows phone platform.
I want to place a button at the end of the listbox entries which will be bound to data from the webservice (I am using a listbox template)
List item 1
List item 2
List item 3
List item 4
List item 5
List item 6
List item 7
List item 8
..Button..
I tried number of things of using grid/stackpanel etc to host the button and all my solutions place the button at the bottom of my screen instead of bottom of all the listbox entries which might span multiple screens.
XAML file I have is below. I want to add a button below the "LBoxItems"
<Grid x:Name="LayoutRoot"
Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid x:Name="ads" >
<!--TitlePanel contains the name of the application and page title-->
<StackPanel Margin="24,24,0,12"
x:Name="SearchTitle">
<StackPanel Orientation="Horizontal">
<TextBlock FontWeight="Bold"
FontSize="{StaticResource PhoneFontSizeLarge}"
Text="{Binding Location}" />
<TextBlock FontSize="{StaticResource PhoneFontSizeLarge}"
Text=" > " />
<TextBlock FontWeight="Bold"
FontSize="{StaticResource PhoneFontSizeLarge}"
Text="{Binding Category}" />
</StackPanel>
<TextBlock FontSize="{StaticResource PhoneFontSizeMedium}"
Text="{Binding Converter={StaticResource SearchHistoryItemSubTitleConverter}}" />
</StackPanel>
</Grid>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentGrid"
Grid.Row="2">
<ListBox x:Name="LBoxItems"
HorizontalAlignment="Left"
Margin="24, 0"
SelectionChanged="LBoxItems_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="{StaticResource PhoneTouchTargetOverhang}" >
<TextBlock FontSize="{StaticResource PhoneFontSizeMediumLarge}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" Foreground="{StaticResource PhoneAccentBrush}"
Text="{Binding Title.Text}" TextWrapping="Wrap" Margin="-4,20,0,0">
</TextBlock>
<TextBlock Text="{Binding PublishDate, Converter={StaticResource ItemPublishDateConverter}}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
<l:SpinnerControl x:Name="SpinnerControl"
Width="55"
Height="55"
Grid.RowSpan="2" />
<TextBlock x:Name="TxtNoResultsMessage"
FontSize="{StaticResource PhoneFontSizeLarge}"
Text="No results found"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Grid.RowSpan="2"
Visibility="Collapsed" />
</Grid>
You could use a ScrollViewer:
<ScrollViewer>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="800"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<ListBox Grid.Row="0">
</ListBox>
<Button Grid.Row="1" Height="30" Content="Test"></Button>
</Grid>
</ScrollViewer>
Simply divide the Grid inside into two rows, the second one being for the Button.
For your specific case it would be:
<Grid x:Name="ContentGrid"
Grid.Row="2">
<ScrollViewer>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="600"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<ListBox x:Name="LBoxItems"
HorizontalAlignment="Left"
Margin="24, 0"
SelectionChanged="LBoxItems_SelectionChanged" Grid.Row="0">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="{StaticResource PhoneTouchTargetOverhang}" >
<TextBlock FontSize="{StaticResource PhoneFontSizeMediumLarge}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" Foreground="{StaticResource PhoneAccentBrush}"
Text="{Binding Title.Text}" TextWrapping="Wrap" Margin="-4,20,0,0">
</TextBlock>
<TextBlock Text="{Binding PublishDate, Converter={StaticResource ItemPublishDateConverter}}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Content="Sample" Height="30" Grid.Row="1" />
</Grid>
</ScrollViewer>
</Grid>
Of course, you can set the appropriate height depending on your situation.
What you want to do, really is to mix and match different items in the DataTemplate. If you're not really happy with how the other solutions work out I might consider adding a button to the datatemplate, but set its visibility to collapsed. Then for the very last entry, set its visibility to visible.
Either way you are in for a bit of a hack, but this way the button is in your list box. If all the button events point to the same handler, and only one is visible, you should be good to go.
I had the same problem and tried using the ScrollViewer approach, however I couldn't get rid of the 'stuck scrolling' issue until I disabled the vertical scrollbar on the listbox. Maybe this will help others too.

WPF ListBox: how to update data with binding

I have listbox that displays information about list of objects:
<ListBox Grid.Column="0" Height="152" Name="CustomersList" HorizontalAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name, Mode=OneWay}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I would show more detailed information about selected item in another block, but I don't know (and can't find) how to bind selected item to those block data context. I guess it should be something like this:
<Grid Grid.Column="1" DataContext="{Binding Path=ItemSelected, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="250"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Id" VerticalAlignment="Center" />
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Path=Id}" VerticalAlignment="Center"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Name" VerticalAlignment="Center"/>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Path=Name}" VerticalAlignment="Center"/>
<StackPanel Grid.Row="2" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="Add new" />
<Button Content="Store changes" />
</StackPanel>
</Grid>
But the problem is that data item to be binded to the grid is not specified anywhere and I don't know how to do that.
Any suggestion would be wellcome.
Thanks!
P.S. I've tried to specify CustomersList.ItemsSource as DataContext for the Grid - this didn't give any result.
You can bind to the SelectedItem property of the ListBox, one way is using ElementName.
<Grid DataContext="{Binding ElementName=CustomersList, Path=SelectedItem}"> </Grid>

Resources