Question

I am working on a little project for a contest in my city..and i just hit a brick wall.The thing is: i am creating a userControl in Blend(let's say a canvas,in wich i have a reactangle..a textblock and an image).My problem is that i can not add this to the listboxitem in WPF by code.Addin the userControl one by one in the designer seems to work..but the software is going to work with a variable number of items for the listbox.

    private void mainPane1_Loaded(object sender, RoutedEventArgs e)
    {
         MessageBox.Show("layout updated");
        questions cq;
        Button btn;

        for (int i = 1; i <= 10; i++)
        {
            btn = new Button();
            btn.Content = "intreb" + i.ToString();
            cq = new questions();
            Canvas.SetZIndex(cq, 17);
            //cq.questionHolder.Text = "intrebare" + i.ToString();
            listaintrebari.Items.Add(cq);
            MessageBox.Show("intrebare" + i.ToString());
            listaintrebari.Items.Add(btn);
            //MessageBox.Show("layout updated");

        }

    }

questions is my UserControl and listaintrebari is the listbox.I tried to add some buttons and it works great...but it seems to hate my userControl.

I am waiting for your thoughts on how to resolve this issue, and if you have any sugestions on what other is best to use in my situation and how..it would be great.Thank you!

Was it helpful?

Solution

Ok, here's some actual code that might help you out. I will be using several WPF concepts that you might want to study further : DataBinding, DataTemplates, ImageSources, ObservableCollections

First you need to create (if you don't have it yet) an underlying class for your Questions. The simplest you can get would be something like this :

 internal class Question
 {
     public ImageSource QuestionImage { get; set; }
     public string QuestionText { get; set; }
 }

Then in your screen's code behind (yes, we are not at MVVM yet), you should create an ObservableCollection of Question and pouplate them with your questions I have smth like this:

public ObservableCollection<Question> Questions { get; private set; }
public MainWindow()
{
    InitializeComponent();
    this.DataContext = this;
    Questions = new ObservableCollection<Question>();

    for (int i = 1; i <= 10; i++)
    {
        var newQ = new Question { QuestionText = "intrebarea " + i.ToString(), QuestionImage = _get your image as a ImageSource here_ };
        Questions.Add(newQ);
    }
}
  • The this.DataContext = this is very important, otherwise your Data Binding will not work.

In your design area, create a list and bind it to the Questions collection you created. The way the question is displayed in the list is driven by the "ItemTemlpate" as below.

<ListBox ItemsSource="{Binding Questions}">
  <ListBox.ItemTemplate>
    <StackPanel>
      <Image Source="{Binding QuestionImage}" Height="20" Width="20"/>
      <TextBlock Margin="5" Text="{Binding QuestionText}" />
    </StackPanel>
  </ListBox.ItemTemplate>
</ListBox>
  • You can replace the I have there with your UserControl contents or event the UserControl itself, but make sure to preserve the Bindings to the objects in your Question class.

Like I said above, many things might not make sense at this point so make sure you read about them : What is a data Binding, What is a DataContext, What is an ObservableCollection. Also, try looking at MVVM when you get a chance...

Lastly, if you are unsure how to get an ImageSource when you have a jpg or png file in your project:

public ImageSource GetImagesource(string location)
{
  var res = new BitmapImage()
  res.BeginInit();
  res.UriSource = new Uri("pack://application:,,,/ApplicationName;component/" + location);
  res.EndInit();

  return res;
}

OTHER TIPS

The right way to handle this kind of situation is by having a data model with a collection of your questions. Then bind your ListBox.ItemsSource to the collection and provide a DataTemplate that uses your UserControl.

Use the ListBox's ItemTemplate to define what you want each instance of your object to look like, then bind the ListBox's ItemsSource to a collection of that type.

You need to create a collection (e.g. List) of your control and bind the collection to the ListBox.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top