Click here to Skip to main content
15,867,686 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi Friends,

How are you all? Actually I am stuck at a point and Now I really need a quick help. I am completely beginner to WPF and I have gone wild while creating a project in it. I am trying to create a software that I can use to interface with one of my hardware. Now I am displaying the output of the hardware, that is received serially into the software, using a custom made control which looks more like a small light. It lights on when I set it's "Glow" boolean Property to true. By the way I would rather talk about the problem. I want to create 'n' instances of this user control where 'n' is the value that I will enter manually in a textbox during runtime and I only know the technique that I had used with WinForms. But with WPF, it's not working.
I have :
Main Window
> Grid
  > Expander 
    > Grid 
      > WrapPanel

Now I need to dynamically create the instances of my User Control in WrapPanel. Can you provide me with some idea of how to progress as I am searching almost everywhere but didn't get any satisfactory answer. I will be very thankful to you.

Regards
Tushar Srivastava
(By the way, Sorry if I used too frank a language)
Posted
Updated 6-Feb-13 2:00am
v2

Skeleton of your XAML:
XML
<Window>
    <Grid>
        <Expander>
            <Grid>
                <WrapPanel Name="myAwesomeNameForAWrapPanel">

                </WrapPanel>
            </Grid>
        </Expander>
    </Grid>
</Window>


In your code-behind:
C#
for(int i = 0; i < 10; i++) 
{
   MyUserControl uc = new MyUserControl();
   myAwesomeNameForAWrapPanel.Children.Add(uc);
}
 
Share this answer
 
v2
Comments
Er. Tushar Srivastava 6-Feb-13 8:06am    
Thank You Very Much Friend(or Sir), Seems like good to me. Just a query, is it fine to redefine wrapPanel object as it has been already defined it in the next Partial Class generated dynamically by Visual Studio? Correct me if I am wrong :)
BotCar 6-Feb-13 8:10am    
Yes, you can name it whatever you want to.
Er. Tushar Srivastava 6-Feb-13 8:12am    
OK Thank you very Much Sir :-)
BotCar 6-Feb-13 8:51am    
OK, I looked up how to access the control in the code-behind. It's as easy as specifying a Name in the XAML. Can't believe I forgot that :-) Updated solution.

Sidenote: Pete O'Hanlon's approach is a much better one, so once you feel comfortable enough with WPF, I suggest you try that instead.
Er. Tushar Srivastava 6-Feb-13 9:06am    
Yes Sure sir, Yet interesting news is that I have solved it using your method already :-) By the way Thank You again for your answer. I will surely be posting up my software code as it will be completed :-)
The things you are looking for are templates and one of the list controls (such as a ListBox). What you would do is create a class that represents the state of the hardware, and then have a class that holds a collection of these hardware state classes. Something like this:
C#
public class HardwareState : INotifyPropertyChanged
{
  private bool lightOn;
  public bool LightOn
  {
    get { return lightOn; }
    set
    {
      if (lightOn != value)
      {
        lightOn = value;
        RaiseNotification("LightOn");
      }
    }
  }
  public event PropertyChangedEventHandler PropertyChanged;
  private void RaiseNotification(string propertyName)
  {
    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler != null)
    {
      handler(this, new PropertyChangedEventArgs(propertyName));
    }
  }
}

public class HardwareStateManager {
  // This is the class that you bind to - populate State with the HardwareState values.
  public ObservableCollection<HardwareState> State { get; set; }
}
Now, you simply need to bind to this class in your view:
XML
<Window.DataContext>
  <vm:HardwareStateManager />
</Window.DataContext>
<Window.Resources>
  <DataTemplate x:Key="LightsTemplate">
    <uc:MyLightControl />
  </DataTemplate>
  <Style TargetType="{x:Type ListBox}">
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
    <Setter Property="ScrollViewer.CanContentScroll" Value="true" />
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="{x:Type ListBox}">
          <ScrollViewer Orientation="Horizontal">
            <ItemsPresenter />
          </ScrollViewer>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>
</Window.Resources>
<Grid>
  <ListBox ItemsSource="{Binding State}" ItemsTemplate="{StaticResource LightsTemplate}" />
</Grid>
Note - I've missed out the definition of the vm and uc namespace here - you would add these as xaml:vm="clr-namespace:...." references in the window declaration.

Finally, I just typed this out in the CP editor window - some of this might be 100% correct in the styling, as I'm just doing this from memory, but it should get you started.
 
Share this answer
 
Comments
Er. Tushar Srivastava 6-Feb-13 7:57am    
Thank You very Much Friend(or Sir), I have just a quick query, I can code, but, can the above method applicable in a way like this. I have an integer variable. I just want to create 'n' instances of User Control and Display it on Screen where 'n' is the value stored in the integer variable. :-)
Pete O'Hanlon 6-Feb-13 8:16am    
That's pretty straightforward, and the reason I used an ObservableCollection. Basically, the way an ObservableCollection works is WPF watches for collection changes to this type (technically, it looks for changes raised from ICollectionChanged which ObservableCollection implements). When you add or remove an item, the user interface is updated to reflect this - so, in this case, all you'd need to do is clear the collection and then add the relevant number of HardwareState instances to the collection. The beauty of the approach I've shown is that all you are manipulating is the data - let WPF handle the rest for you, so you don't need to manage adding or removing controls yourself.
Er. Tushar Srivastava 6-Feb-13 8:20am    
Thank you Very Much Sir, I will definitely try this approach too but before that I have to master few of the fundamentals of WPF as I am hobbyist and just love to play with codes. :-)
Pete O'Hanlon 6-Feb-13 8:24am    
Fair enough. This is generally the recommended approach, and makes heavy use of a pattern called MVVM. As you play with WPF, you really should read up on that.
Er. Tushar Srivastava 6-Feb-13 8:41am    
Yes, actually I have to get deep into the WPF before doing anything that uses advanced techniques and I am just going to get a good Book on advanced approach in WPF to get stated as I am finding it very interesting. :-)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900