0

My WPF application has a listbox with multiple items. On each item, we have an image and a textbox.

See XAML below:

      <ListBox x:Name="lstMagic" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="10,200,10,0" Width="Auto" Height="558" Background="{x:Null}" BorderBrush="Transparent">

            <ListBoxItem>
                <StackPanel Orientation="Horizontal">
                    <Image Source="images/plates/pig.jpg" Margin="0,0,5,0" Width="72"/>
                    <TextBox IsReadOnly="True"  Background="{x:Null}" Foreground="White" Width="912">Some Magic is going to happen</TextBox>
                </StackPanel>
            </ListBoxItem>

So the list begins with the pigs as expected. IN front of the pig, he loads the pig.jpg sucessfully.

Beside that form section, I have a button. I was able to do some magic on that button to add a new listBoxItem.

        private void btnDoMagic(object sender, RoutedEventArgs e)
    {
        ListBoxItem newMagic = new ListBoxItem();
        Image imageCurrent = new Image();
        imageCurrent.Source = new BitmapImage(new Uri("images/plates/someOtherImage.jpg", UriKind.RelativeOrAbsolute));
        newMagic.Content = imageCurrent;
        lstCardapio.Items.Add(newMagic);
    }
}

This function works, and adds the image successfully to the list! But I have some questions: How can I make just like my first XAML? An image and a textbox? How can I add these at my button event?

I will need this done because we will get these items from our database, so we must load these dynamically.

Mike Schwartz
  • 2,182
  • 1
  • 17
  • 26
Malavos
  • 429
  • 3
  • 12
  • 27
  • 1
    Don't create or manipulate UI elements in procedural code in WPF. That's what XAML is for. Create a proper ViewModel with an `ObservableCollection` and Bind the `ListBox.ItemsSource` to that collection. Then use the `ListBox.ItemTemplate` property to define what the UI will look like for each item. – Federico Berasategui Feb 05 '14 at 16:30
  • 1
    because WPF is not intended to be used in that way. You will end up with a lot of unneeded, difficult to maintain code. Create a proper ViewModel and all your problems will magically disappear. – Federico Berasategui Feb 05 '14 at 16:39
  • 1
    See [this answer](http://stackoverflow.com/a/21315083/643085) – Federico Berasategui Feb 05 '14 at 16:43

1 Answers1

2

If I understand correctly, you would like to duplicate exactly your XAML hierarchy, except in code and then add it to the ListBox?

If you want to create the controls in-code at that point just straight up, you could use something like this:

    // This method creates your controls and returns a listBoxItem with the specified content.
    private ListBoxItem createObject(String imgSource, String text)
    {
        var newImage = new Image() 
            { 
                Source = new BitmapImage(new Uri(imgSource, UriKind.RelativeOrAbsolute)), 
                Width = 72, 
                Margin = new Thickness(0, 0, 5, 0) 
            };
        var newTextBox = new TextBox() 
            { 
                IsReadOnly = true, 
                Background = Brushes.Transparent, 
                Foreground = Brushes.White, 
                Width = 912, 
                Text = text 
            };

        var newStackPanel = new StackPanel() { Orientation = Orientation.Horizontal };

        newStackPanel.Children.Add(newImage);
        newStackPanel.Children.Add(newTextBox);

        return new ListBoxItem() { Content = newStackPanel };
    }


    private void btnDoMagic(object sender, RoutedEventArgs e)
    {
        // Get your URI and textbox text here, and use them as arguments below.

        1stMagic.Items.Add(createObject("Sample URI", "Sample Textbox Content"));
    }

Granted, it's not particularly neat and requires you are aware of what the XAML it corresponds to is whenever you modify it, and you lose track of the controls once you leave the event handler (as they have no names or ways to directly get to them), but it should work.

If you want to modify the created objects further you could iterate through 1stMagic.Items, or you could add the created controls to a private internal list you maintain in code and manage them that way.

TernaryTopiary
  • 436
  • 5
  • 17
  • That solved it. But as @HighCore said, it's better to create my bindings... I'm studying to do so. Anyway, that answer solved the question itself, and it was of great help! Thanks! – Malavos Feb 05 '14 at 20:24