Reputation: 3
I'm rather new to WPF and MVVM and now I came across a problem which I did not manage to find a solution so far. I am updating an old program which is using Windows.Forms. Since I am currently reading and learning about WPF, I thought it a good idea to redo the program in WPF.
My program reads an ASCII-File in a special format and creates a list of Fragment
objects from it. Then the list is displayed in a dynamically created GUI. The Fragment
object look as follows:
public class Fragment
{
public string Name { get; set; }
public List<Value> Values { get; set; }
public int ActiveIndex { get; set; }
}
public class Value
{
public string Name { get; set; }
public int BitValue { get; set; }
}
So: Each Fragment
can have multiple Value
objects in the property. The active value is also read from the ASCII file and its index (index from the Value in the List<Value>
) is saved in the ActiveIndex
property.
I have prepared a simple XAML-Layout where the results shall be displayed.
<ScrollViewer VerticalScrollBarVisibility="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Margin="0, 3"></StackPanel>
<GridSplitter Grid.Column="1" ResizeDirection="Columns" Background="DarkGray" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ResizeBehavior="PreviousAndNext" IsEnabled="True" Width="1"></GridSplitter>
<StackPanel Grid.Column="2" Margin="0, 3"></StackPanel>
</Grid>
</ScrollViewer>
So: in the first StackPanel I want to display all Fragment.Name
as Labels, in the second StackPanel I want to create a ComboBox for each Fragment
which carries all Fragment.Values
showing the Value.Name
property. The ActiveIndex
is bound to the SelectedIndex of the combobox.
I can perfectly do that in the code behind file but that would give me and everyone else, who sees that, a serious headache. I understand, that it is possible to do that in XAML, but I do not really get, how it is done. Can anyone hint me in the correct direction who such a behaviour can be achieved? Also, if there are better GUI ways to handle that, I am completely open for suggestions. The current one ist just a simple transfer from the Windows.Forms version of the tool.
Upvotes: 0
Views: 771
Reputation: 8743
You can use the ItemsControl:
<ScrollViewer VerticalScrollBarVisibility="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ItemsControl ItemsSource="{Binding NameOfYourListOfFragments}">
<ItemsControl.ItemsPanel>
<StackPanel Margin="0, 3"></StackPanel>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<Label Content="{Binding Name}"/>
</itemsControl.ItemsTemplate>
</ItemsControl>
<GridSplitter Grid.Column="1" ResizeDirection="Columns" Background="DarkGray" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ResizeBehavior="PreviousAndNext" IsEnabled="True" Width="1"></GridSplitter>
<ItemsControl Grid.Column="2" ItemsSource="{Binding NameOfYourListOfFragments}">
<ItemsControl.ItemsPanel>
<StackPanel Margin="0, 3"></StackPanel>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemsTemplate>
<Combobox ItemsSource="{Binding Values}" DisplayMemberPath="Name" SelectedIndex="{Binding ActiveIndex}"/>
</ItemsControl.ItemsTemplate>
</ItemsControl>
</Grid>
</ScrollViewer>
With ItemsPanel
, you tell the ItemsControl
, in which kind of Panel your GUI elements should be arranged. The ItemTemplate
tell you, what the element in your ItemsControl look like.
If you use an ObservableCollection
, you can also add or remove entries at runtime and the GUI will be updated automatically.
In order to make the binding fully work, it's propable that your classes also have to impelement INotifyPropertyChanged
and you have to invoke the PropertyChanged
event in the setter of your properties.
Upvotes: 1