Binding Visibility of StackPanel in a ListBox.ItemTemplate
-
Tuesday, September 20, 2011 5:37 PM
Hi,
I'm trying to setup an item template which has a couple of nested StackPanels in it. I'm trying to set the visibility of one of the panels to the IsSelected proprety of the ListBoxItem. I've tried this with no luck:
<ListBox Name="listBox1" Margin="0,0,0,0" SelectionChanged="listBox1_SelectionChanged"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Vertical"> <StackPanel Orientation="Horizontal"> <TextBlock Text="This is where the person's info goes, picture, name, and stuff, the color of the row changes based on his status, and stuff like that" TextWrapping="Wrap" Height="100" Width="600"/> </StackPanel> <StackPanel Orientation="Horizontal" x:Name="buttonsPanel" Visibility="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected, Converter={StaticResource BooleanToVisibilityConverter}}" > <RadioButton x:Name="presentButton" Content="Present" Width="100" ClickMode="Press" IsTabStop="False"/> <RadioButton x:Name="absentButton" Content="Absent" Width="100" ClickMode="Press" IsTabStop="False"/> <RadioButton x:Name="excusedButton" Content="Excused" Width="100" ClickMode="Press" IsTabStop="False"/> </StackPanel> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox>The point is that the last StackPanel should only be displayed for the selected item.
Does anyone know what I'm doing wrong here?
Thanks
All Replies
-
Tuesday, September 20, 2011 6:54 PM
which version of Silverlight? If 5, you can use Ancestor RelativeSource binding to get a reference to the ListBoxItem which is the control you're trying to reference. Otherwise, maybe you could get creative with a converter and walk up the tree until you find a ListBoxItem.
-
Tuesday, September 20, 2011 9:08 PM
I'm still using Silverlight 4.
I guess I'll keep looking for a solution, since I can't upgrade at the moment.
-
Thursday, September 22, 2011 5:37 AMModerator
Hi Ali,
Below is my test code, and the StackPanel only be displayed for the selected item. You may have a try.
.xaml
<UserControl x:Class="BindingVisibility.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:myproject="clr-namespace:BindingVisibility" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <UserControl.Resources> <myproject:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="White"> <ListBox Name="listBox1" Margin="0,0,0,0" > <ListBox.ItemContainerStyle> <Style TargetType="ListBoxItem"> <Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}" > </Setter> </Style> </ListBox.ItemContainerStyle> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Vertical" > <StackPanel Orientation="Horizontal"> <TextBlock Text="This is where the person's info goes, picture, name, and stuff, the color of the row changes based on his status, and stuff like that" TextWrapping="Wrap" Height="100" Width="600"/> </StackPanel> <TextBlock Text="{Binding Name}" /> <StackPanel Orientation="Horizontal" x:Name="buttonsPanel" Visibility="{Binding Path=IsSelected,Converter={StaticResource BooleanToVisibilityConverter},Mode=TwoWay}" > <RadioButton x:Name="presentButton" Content="Present" Width="100" ClickMode="Press" IsTabStop="False"/> <RadioButton x:Name="absentButton" Content="Absent" Width="100" ClickMode="Press" IsTabStop="False"/> <RadioButton x:Name="excusedButton" Content="Excused" Width="100" ClickMode="Press" IsTabStop="False"/> </StackPanel> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid> </UserControl>.cs
using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.Collections.ObjectModel; using System.Windows.Data; using System.ComponentModel; namespace BindingVisibility { public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); listBox1.ItemsSource = GridData.GetData(); } } public class GridData : INotifyPropertyChanged { public string Name { get; set; } public int Age { get; set; } public bool Male { get; set; } private bool isSelected; public bool IsSelected { get { return isSelected; } set { isSelected = value; NotifyPropertyChanged("IsSelected"); } } public static ObservableCollection<GridData> GetData() { ObservableCollection<GridData> data = new ObservableCollection<GridData>(); data.Add(new GridData() { Name = "John Doe", Age = 30, Male = true, IsSelected = false }); data.Add(new GridData() { Name = "Jane Doe", Age = 32, Male = false, IsSelected = false }); data.Add(new GridData() { Name = "Jason Smith", Age = 54, Male = true, IsSelected = false }); data.Add(new GridData() { Name = "Kayli Jayne", Age = 25, Male = false, IsSelected = false }); return data; } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } } }Any question on this issue, please let me know.
Best Regards,
-
Thursday, September 22, 2011 5:40 PM
Hi Haixia,
Thanks for the reply.
I tried to run your code, but ran into an exception when InitializeComponent is called:
{System.NotSupportedException: Cannot set read-only property ''.
at MS.Internal.XamlMemberInfo.SetValue(Object target, Object value)
at MS.Internal.XamlManagedRuntimeRPInvokes.SetValue(XamlTypeToken inType, XamlQualifiedObject& inObj, XamlPropertyToken inProperty, XamlQualifiedObject& inValue)}It is on this line:
<Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}" >
I'm not realy sure why. According to the docs IsSelected is not a read only property.
-
Thursday, September 22, 2011 8:48 PMModerator
Hi Ali,
I suspect that you may have missed somthing, such as a reference or namespace. I have upload my test project( BooleanToVisibilityConvertertest) to skydrive , you may have a look.
Best Regards,
-
Thursday, September 22, 2011 9:44 PM
I get the same exact error running your sample application.
What version of Silverlight are you using?
-
Thursday, September 22, 2011 9:49 PMModerator
Hi Ali,
I am using Silverlight 4, and have these installed: VS 2010, Microsoft Silverlight 4 Toolkit April 2010,Microsoft Silverlight 4 SDK.
Best Regards,
-
Thursday, September 22, 2011 9:52 PM
That's exactly what I'm using! Wonder why it blows up on mine?
-
Thursday, September 22, 2011 9:58 PMModerator
Hi Ali,
Do you have same issue when running other Silverlight applications? Please check if you have these three (VS 2010, Microsoft Silverlight 4 Toolkit April 2010 ,Microsoft Silverlight 4 SDK) installed.
Best Regards,
-
Thursday, September 22, 2011 10:17 PMNope, no problems with other Silverlight Apps. I double checked the version of the SDK and toolkit and they are the same as yours. And I'm using VS2010.
-
Thursday, September 22, 2011 11:04 PMModerator
Hi Ali,
The test application I posted above indeed created at Silverlight 4 version. The issue is not arise at my side maybe have something to do with I have installed Silverlight 5 SDK on my machine.
Binding in style setters allows bindings to be used within styles to reference other properties is a new feature of Silverlight 5. So I will suggest you to install Silverlight 5.
If you really don't want to install Silverlight 5, you may try this Setter value binding helper.
Best Regards,
-
Friday, September 23, 2011 7:23 AMHi, It is dependency no reason to use Converter. However ListBox is Visaul Tree so that you can bind to ElementName. private Visibility _adminButtonsVisibility; public Visibility AdminButtonsVisibility { get { return _adminButtonsVisibility; } set { if (_adminButtonsVisibility != value) { _adminButtonsVisibility = value; OnPropertyChanged("AdminButtonsVisibility"); } } }
-
Friday, September 23, 2011 7:23 AM
private Visibility _adminButtonsVisibility;
public Visibility AdminButtonsVisibility
{
get { return _adminButtonsVisibility; }
set
{
if (_adminButtonsVisibility != value)
{
_adminButtonsVisibility = value;
OnPropertyChanged("AdminButtonsVisibility");
}
}
} -
Sunday, September 25, 2011 2:51 PM
Thai, you really need to read and understand the thread before your post. The question is:
How do I bind a stackpanel Visibility property to my list box item IsSelected property. How are you going to do that without a converter?
Ali, The reason why you are getting that error is that you can't use binding in a setter property of a style in Silverlight 4:
Although you can in Silverlight 5:
http://www.kunal-chowdhury.com/2011/05/binding-on-style-setter-in-silverlight.html
So maybe Haixia is running Silverlight 5.

