Control size of ListBoxItem (with DataTemplate) using RadioButtons - silverlight

I´m displaying images in a ListBox and i want to control the size (small, medium, big) of the images with RadionButtons. The ItemsSource of the ListBox is bound to a property of a viewmodel. My current solution is to use an Image for each size and bind the Visibility of each Image to the IsChecked property to the corresponding RadioButton. But i wonder if there is a better solution to get it work, especially using bindings and not duplicating items for various sizes. Using animations for the size changes would also be great.
Here´s what i have so far.
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListBox ItemsSource="{Binding Images}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Image x:Name="smallImage" Width="80" Height="45" Source="{Binding}" Visibility="{Binding IsChecked, ElementName=SmallSizeChecked, Converter={StaticResource boolToVisibility}}" />
<Image x:Name="mediumImage" Width="160" Height="90" Source="{Binding}" Visibility="{Binding IsChecked, ElementName=MediumSizeChecked, Converter={StaticResource boolToVisibility}}"/>
<Image x:Name="bigImage" Width="320" Height="180" Source="{Binding}" Visibility="{Binding IsChecked, ElementName=BigSizeChecked, Converter={StaticResource boolToVisibility}}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<RadioButton Content="small" Margin="0,0,10,0" GroupName="ItemSize" x:Name="SmallSizeChecked" />
<RadioButton Content="medium" Margin="0,0,10,0" GroupName="ItemSize" x:Name="MediumSizeChecked" IsChecked="True" />
<RadioButton Content="big" GroupName="ItemSize" x:Name="BigSizeChecked"/>
</StackPanel>
</Grid>

This can be easily achieved by using IValueConverters with parameters.
here is more elegant way then converters. i have not compiled it but will work after some fixes.
C#:
public class VM
{
public List<string> Images { get; set; }
public bool SmallSizeChecked { get; set; }
public bool MediumSizeChecked { get; set; }
public bool BigSizeChecked { get; set; }
public int size
{
get
{
if(SmallSizeChecked) return 100;
if(MediumSizeChecked) return 200;
if(BigSizeChecked) return 300;
return 100;
}
}
}
XAML:
<local:VM x:Key="mv" />
<RadioButton x:name="SmallSizeChecked" ischecked="{Binding mv.SmallSizeChecked, Mode=Twoway}"/>
<RadioButton x:name="MediumSizeChecked" ischecked="{Binding mv.MediumSizeChecked, Mode=Twoway/>
<RadioButton x:name="BigSizeChecked" ischecked="{Binding mv.BigSizeChecked, Mode=Twoway}"/>
<ListBox ItemsSource="{Binding mv.Images}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Image x:Name="img" Source="{Binding}" Width="80" Height="{Binding Path=size,Source={staticResource mv}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I'm sure you will get the idea and will extend it for Width property too.
Dipak.

Related

Can you create ItemTemplate for Stack Panels with bindings?

I have a stack panel of stack panels with similar controls. Could a template be used instead? Each field is a property of an Custom Object.
<StackPanel Margin="10,0,0,0">
<StackPanel x:Name="ReferenceStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="Reference" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=UReference, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
<StackPanel x:Name="TitleStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="Title" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=Title, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
<StackPanel x:Name="SponsorStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="Sponsor" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=Sponsor, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
<StackPanel x:Name="AlignmentStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="Alignment" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=Alignment, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
<StackPanel x:Name="NTAStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="NTA" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=NTA, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
<StackPanel x:Name="KeywordsStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="Keywords" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=Keywords, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
<StackPanel x:Name="FocusAreasStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="FocusAreas" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=FocusAreas, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
<StackPanel x:Name="PlatformStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="Platform" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=Platform, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
<StackPanel x:Name="FiscalYearStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="FiscalYear" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=FiscalYear, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
<StackPanel x:Name="OriginatingDocumentStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="OriginatingDocument" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=OriginatingDocument, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
<StackPanel x:Name="RecommendationsStackPanel" Margin="5" Visibility="{Binding}">
<Label Content="Recommendations" Style="{StaticResource LabelStyle}"/>
<Controls:MarkingsTextbox Value="{Binding Path=Recommendations, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
</StackPanel>
</StackPanel>
I was thinking something like this but it didn't work.
<DataTemplate x:Key="Template">
<StackPanel>
<Label Content="{Binding}" />
<TextBox Text="{Binding}"/>
</StackPanel>
</DataTemplate>
I am also reading something about ContentControl but not sure how they work. It is one object I am trying to display, in an edit properties view.
The simplest solution to this would be if it's ok to have your label and textbox side by side.
Then you could use a propertygrid:
https://github.com/xceedsoftware/wpftoolkit/wiki/PropertyGrid
The toolkit is not free for commercial use, however, the source is available and you could take that and customise/simplify it for your usage.
If that does not suit then you could use reflection to build out a collection of property viewmodels which have PropertyName and PropertyValue.
Add them to a List you bind to itemssource of an itemscontrol.
You can then template each to whatever you like.
I'm not clear what that Visibility binding is all about, can't work out what the intent is there.
You could, however, use an attribute to control which properties are displayed.
The following proof of concept iterates properties to build out a list. It is very quick and dirty and intended just to get you started rather than a cut and paste solution.
MainWindow
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<ItemsControl ItemsSource="{Binding PropertyValues}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}"/>
<TextBox Text="{Binding Value}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
MainWindowViewModels and some classes.
public partial class MainWindowViewModel : ObservableValidator
{
[ObservableProperty]
private List<PropertyNameValue> propertyValues = new();
private PropertyInfo[] propertyList = typeof(Thingummy).GetProperties();
private Thingummy thing = new Thingummy { Reference="AAAAA", Sponsor="BBBB", Title="CCCC"};
private void GetProperties()
{
foreach (PropertyInfo property in propertyList)
{
PropertyNameValue pnv = new PropertyNameValue{ Name= property.Name, Value=property.GetValue(thing).ToString() };
PropertyValues.Add(pnv);
}
}
private void SetProperties()
{
for (int i = 0; i < propertyList.Length; i++)
{
propertyList[i].SetValue(thing, PropertyValues[i].Value);
}
}
public MainWindowViewModel()
{
GetProperties();
}
}
public class Thingummy
{
public string Reference { get; set; }
public string Title { get; set; }
public string Sponsor { get; set; }
}
public class PropertyNameValue
{
public string Name { get; set; }
public string Value { get; set; }
}
I don't know what type your class is you're editing. I've called mine Thingummy and of course it only has the first few properties.
There's no save button but that'd call SetProperties.
You could potentially make this generic and pass in a type to a generic viewmodel if you put your mind to it.
Make the itemssource a list and define different viewmodels for string, double etc. Define a template for each type. Perhaps put any get/ set logic in there as well.
Anyhow, this spins up and I can edit ok.

How to use WrapPanel's DataTemplate

I've a WrapPanel to show some elements. But I want to use DataTemplate to show them.
Here is my XAML code of WrapPanel
<WrapPanel Margin="10,57,12,10" x:Name="wrp1">
<WrapPanel.Resources>
<DataTemplate DataType="{x:Type local:DateItem}">
<Grid VerticalAlignment="Top" HorizontalAlignment="Stretch" Width="250" Height="300" Background="Blue">
<Label Content="{Binding Path=DateString}" FontSize="20" Cursor="Hand" Foreground="White" Background="Red" FontWeight="Bold" VerticalAlignment="Bottom" HorizontalAlignment="Left" Height="38" VerticalContentAlignment="Center" Padding="5,0,5,0"/>
</Grid>
</DataTemplate>
</WrapPanel.Resources>
</WrapPanel>
And this is the code of DateItem
public class DateItem : UIElement
{
public string DateString { get; set; }
}
When the window initialized, i'm creating one DateItem with DateString parameter and adding that to WrapPanel as child.
DateItem di = new DateItem();
di.DateString = "28.04.2014";
wrp1.Children.Add(di);
I think everything is fine but wrap panel shows nothing :(
Can you help me with this?
You have confused UI controls with DataTemplates which is used to define the presentation of your data. To render data, you have to set content of control which can be done using ContentControl.
Also, you can use ItemsControl if you want to add multiple times.
XAML:
<WrapPanel x:Name="wrp1">
<WrapPanel.Resources>
<DataTemplate DataType="{x:Type local:DateItem}">
<Grid VerticalAlignment="Top" HorizontalAlignment="Stretch" Width="250"
Height="300" Background="Blue">
<Label Content="{Binding Path=DateString}" FontSize="20" Cursor="Hand"
Foreground="White" Background="Red" FontWeight="Bold"
VerticalAlignment="Bottom" HorizontalAlignment="Left"
Height="38" VerticalContentAlignment="Center"
Padding="5,0,5,0"/>
</Grid>
</DataTemplate>
</WrapPanel.Resources>
<ItemsControl x:Name="itemsControl"/>
</WrapPanel>
Code behind:
DateItem di = new DateItem();
di.DateString = "28.04.2014";
itemsControl.Items.Add(di);
DateItem:
public class DateItem
{
public string DateString { get; set; }
}
In case you still interested in rendering it as a Control, you have to define default Style and not default template.
XAML:
<WrapPanel x:Name="wrp1">
<WrapPanel.Resources>
<Style TargetType="{x:Type local:DateItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid VerticalAlignment="Top" HorizontalAlignment="Stretch"
Width="250" Height="300" Background="Blue">
<Label
Content="{Binding Path=DateString, RelativeSource=
{RelativeSource Mode=TemplatedParent}}"
FontSize="20" Cursor="Hand" Foreground="White"
Background="Red" FontWeight="Bold"
VerticalAlignment="Bottom"
HorizontalAlignment="Left"
Height="38" VerticalContentAlignment="Center"
Padding="5,0,5,0"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</WrapPanel.Resources>
</WrapPanel>
Code behind:
DateItem di = new DateItem();
di.DateString = "28.04.2014";
wrp1.Children.Add(di);
DateItem:
public class DateItem : Control
{
public string DateString { get; set; }
}

WPF Binding to child of current item not updating

I am currently binding to an ObservableCollection using an ICollectionView, myCollectionView. The contents of that collection are being selected from a ComboBox. Each collection item, myCollectionItem, has a VisualBrush, myVisualBrush, as a child and the CurrentItem's brush is displayed in a preview panel.
The collection item also a child object, myItemChild, which contains a number of its own properties that are used to generate a slider. This slider alters properties on the preview panel.
This all works as expected.
When the CurrentItem of the Collectionview is changed the preview panel updates correctly but the slider continues to show the previous CurrentItem's myItemChild.
The change to myItemChild is not being raised, how should I handle this situation?
Its highly probable I have missed something obvious so any pointers appreciated.
Regards
Rob
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<!-- Combo Box for selection of item-->
<ComboBox Grid.Row="0" ItemsSource="{Binding myCollectionView, Mode=TwoWay}" IsSynchronizedWithCurrentItem="True">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type vm:myCollectionItem}" >
<StackPanel>
<Rectangle Height="40" Width="40" Fill="{Binding myVisualBrush}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<!-- Panel to preview item-->
<ContentControl Grid.Row="1" Content="{Binding myCollectionView/}">
<ContentControl.ContentTemplate>
<DataTemplate DataType="{x:Type vm:myCollectionItem}" >
<Rectangle Margin="20" Fill="{Binding myVisualBrush}" />
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
<!-- Slider to edit item-->
<ContentControl Grid.Row="2" Content="{Binding myCollectionView/}">
<ContentControl.ContentTemplate>
<DataTemplate DataType="{x:Type vm:myCollectionItem}" >
<ContentControl Content="{Binding myItemChild}">
<ContentControl.ContentTemplate>
<DataTemplate DataType="{x:Type vm:myCollectionItemChild}" >
<StackPanel>
<Label Content="{Binding myValueLabel, Mode=OneWay}"/>
<Slider Value="{Binding myValue, Mode=TwoWay}" Maximum="{Binding myValueMax}" Minimum="{Binding myValueMin}"/>
</StackPanel>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
</Grid>
I tried to reproduce your problem, but it works without problems.
Here is my code-behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var items = new ObservableCollection<myCollectionItem>{
new myCollectionItem(Brushes.Red, new myCollectionItemChild("Red", 15, 0, 80)),
new myCollectionItem(Brushes.Green, new myCollectionItemChild("Green", 0.7, 0, 1)),
new myCollectionItem(Brushes.Purple, new myCollectionItemChild("Purple", 22,11,33))};
this.DataContext = new Model { myCollectionView = items };
}
}
public class Model
{
public ObservableCollection<myCollectionItem> myCollectionView { get; set; }
}
public class myCollectionItem
{
public myCollectionItem(Brush br, myCollectionItemChild child)
{
this.myVisualBrush = br;
this.myItemChild = child;
}
public Brush myVisualBrush { get; set; }
public myCollectionItemChild myItemChild { get; set; }
}
public class myCollectionItemChild
{
public myCollectionItemChild(string label, double val, double min, double max)
{
this.myValueLabel = label;
this.myValue = val;
this.myValueMin = min;
this.myValueMax = max;
}
public string myValueLabel { get; set; }
public double myValue { get; set; }
public double myValueMax { get; set; }
public double myValueMin { get; set; }
}
Also, you don't need to use control templates. It can be written more clearly:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="80"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<!-- Combo Box for selection of item-->
<ComboBox Grid.Row="0" ItemsSource="{Binding myCollectionView, Mode=TwoWay}" IsSynchronizedWithCurrentItem="True">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type vm:myCollectionItem}" >
<StackPanel>
<Rectangle Height="40" Width="40" Fill="{Binding myVisualBrush}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<!-- Panel to preview item-->
<Rectangle Margin="20" Fill="{Binding myCollectionView/myVisualBrush}" Grid.Row="1" />
<!-- Slider to edit item-->
<StackPanel Grid.Row="2" DataContext="{Binding myCollectionView/myItemChild}">
<Label Content="{Binding myValueLabel, Mode=OneWay}"/>
<Slider Value="{Binding myValue, Mode=TwoWay}" Maximum="{Binding myValueMax}" Minimum="{Binding myValueMin}"/>
</StackPanel>
</Grid>

Is it possible to dynamically choose which Control to render based on bindable attribute in Silverlight 4?

I have a ListBox with an ItemTemplate which renders a Grid with two columns. The first column is a TextBlock and the second is a ComboBox.
The idea is to present to the user a list of questions and a Combo from which the user can choose an answer. This works ok with this xaml:
<ListBox x:Name="QAListBox" ScrollViewer.VerticalScrollBarVisibility="Auto" SelectedIndex="-1"
ItemsSource="{Binding Questions}" IsTabStop="True" TabIndex="5"
ScrollViewer.HorizontalScrollBarVisibility="Auto" Margin="10" BorderThickness="0">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid d:DesignWidth="931" d:DesignHeight="61" d:IsLocked="True" Margin="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".80*" MinWidth="800"/>
<ColumnDefinition Width=".20*" MinWidth="200"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=QuestionText}" Padding="10" FontSize="21.333" FontWeight="Bold" Margin="0" Grid.Column="0" d:IsLocked="True" />
<ComboBox ItemsSource="{Binding Path=AnswerAlternative}"
SelectedValue="{Binding Path=QuestionsAndAnswers}" SelectedValuePath="AnswerAlternativeId"
FontSize="21.333" FontWeight="Bold" Grid.Column="1" Margin="60,0,0,0" d:IsLocked="True" SelectionChanged="ComboBox_SelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=AnswerText, Mode=TwoWay}" BorderThickness="0">
<TextBox.Background>
<SolidColorBrush />
</TextBox.Background>
</TextBox>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The reason for putting a TextBox inside the DataTemplate (in stead of TextBlock), is my first attempt on allowing the user to enter free text in addition to choosing from the dropdown. It kind of work, however, the TextBox is inside the ComboBox. That is not what I want.
Is it possible to have a "plain" TextBox render in stead of a ComboBox based upon some bindable attribute?
So that if an attribute InputType==FreeText the view is rendered with a TextBox and if the attribute is Inputtype==Combo it is rendered as above?
t.
A simplistic solution to your specific problem is to include both and use a value converter on the Visibility property:-
public class EqualityToValueConverter<T> : IValueConverter
{
public T FalseValue { get; set; }
public T TrueValue { get; set; }
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
return FalseValue;
else
return value.ToString().Equals(parameter) ? TrueValue : FalseValue;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value != null && value.Equals(TrueValue) ? parameter : null;
}
}
public class EqualityToVisibilityConverter : EqualityToValueConverter<Visibility> { }
Then your Xaml can look like:-
<ListBox x:Name="QAListBox" ScrollViewer.VerticalScrollBarVisibility="Auto" SelectedIndex="-1"
ItemsSource="{Binding Questions}" IsTabStop="True" TabIndex="5"
ScrollViewer.HorizontalScrollBarVisibility="Auto" Margin="10" BorderThickness="0">
<ListBox.Resources>
<local:EqualityToVisibilityConverter x:Key="converter"
TrueValue="Visible" FalseValue="Collapsed" />
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid d:DesignWidth="931" d:DesignHeight="61" d:IsLocked="True" Margin="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".80*" MinWidth="800"/>
<ColumnDefinition Width=".20*" MinWidth="200"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=QuestionText}" Padding="10" FontSize="21.333" FontWeight="Bold" Margin="0" Grid.Column="0" d:IsLocked="True" />
<ComboBox ItemsSource="{Binding Path=AnswerAlternative}"
SelectedValue="{Binding Path=QuestionsAndAnswers}" SelectedValuePath="AnswerAlternativeId"
FontSize="21.333" FontWeight="Bold" Grid.Column="1" Margin="60,0,0,0" d:IsLocked="True" SelectionChanged="ComboBox_SelectionChanged"
Visibility={Binding InputType, Converter={StaticResource converter}, ConverterParameter=Combo}">
<TextBox Text="{Binding Path=AnswerText, Mode=TwoWay}" Grid.Column="1" Margin="60,0,0,0"
Visibility={Binding InputType, Converter={StaticResource converter}, ConverterParameter=FreeText}">
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
More sophisticated solutions would use a sub-class of ListBox and an override or PrepareContainerForItemOverride to allow variety of ItemTemplates to be assigned. However I think that would be overkill for this problem.

Silverlight Data Binding for Collection in Stack Panel

I'm new to Silverlight, so I don't have a complete grasp of all the controls at my disposal. What I would like to do is use databinding and a view model to maintain a collection of items. Here is some mock code for what I'd like to do:
Model
public class MyItem
{
public string DisplayText { get; set; }
public bool Enabled { get; set; }
}
ViewModel
public class MyViewModel : INotifyPropertyChanged
{
private ObservableCollection<MyItem> _myItems = new ObservableCollection<MyItem>();
public ObservableCollection<MyItem> MyItems
{
get { return _myItems; }
set
{
_myItems = value
NotifyPropertyChanged(this, "MyItems");
}
}
}
View
<Grid x:Name="LayoutRoot" Background="White">
<StackPanel ItemsSource="{Binding MyItems}">
<StackPanel Orientation="Horizontal">
<CheckBox "{Binding Enabled, Mode=TwoWay}"></CheckBox>
<TextBlock Text="{Binding DisplayText, Mode=TwoWay}" />
</StackPanel>
</StackPanel>
</Grid>
So my end goal would be that every time I add another MyItem to the MyItems collection it would create a new StackPanel with checkbox and textblock. I don't have to use a stack panel but just thought I'd use that for this sample.
Looks like you want a <ListBox>, then set the <ListBox.ItemTemplate> to your <StackPanel> something like this.....
<ListBox ItemsSource=”{Binding Classes, Source={StaticResource model}}”>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox "{Binding Enabled, Mode=TwoWay}"/>
<TextBlock Text="{Binding DisplayText, Mode=TwoWay}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
here is a great example (it's WPF, but should only be minor changes for silverlight)
yes, looks like you want a <ListBox>
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SilverlightApplication4.MainPage"
Width="640" Height="480">
<UserControl.Resources>
<DataTemplate x:Key="ItemTemplate">
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding Enabled, Mode=TwoWay}"/>
<TextBlock Text="{Binding DisplayText}"/>
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White" DataContext="{Binding Source={StaticResource SampleDataSource}}">
<ListBox Margin="0,0,8,0" ItemTemplate="{StaticResource ItemTemplate}" ItemsSource="{Binding Collection}"/>
</Grid>
This code will give you a ListBox with all your Data bound to a Checkbox and TextBlock with the Checkbox first and TextBox next to it.

Resources