Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
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 6-Feb-13 2:28am
Edited 6-Feb-13 3:00am
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

Skeleton of your XAML:
<Window>
    <Grid>
        <Expander>
            <Grid>
                <WrapPanel Name="myAwesomeNameForAWrapPanel">
 
                </WrapPanel>
            </Grid>
        </Expander>
    </Grid>
</Window>
 
In your code-behind:
for(int i = 0; i < 10; i++) 
{
   MyUserControl uc = new MyUserControl();
   myAwesomeNameForAWrapPanel.Children.Add(uc);
}
  Permalink  
v2
Comments
Tushar Sriv at 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 :)
TheOtherCPian at 6-Feb-13 8:10am
   
Yes, you can name it whatever you want to.
Tushar Sriv at 6-Feb-13 8:12am
   
OK Thank you very Much Sir :-)
TheOtherCPian at 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.
Tushar Sriv at 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 :-)
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

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:
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:
<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.
  Permalink  
Comments
Tushar Sriv at 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 at 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.
Tushar Sriv at 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 at 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.
Tushar Sriv at 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. :-)
Tushar Sriv at 6-Feb-13 8:01am
   
Sorry, actually, I have reviewed my question and updated it. :-(

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

  Print Answers RSS
0 OriginalGriff 290
1 Jochen Arndt 165
2 DamithSL 125
3 PIEBALDconsult 110
4 Garth J Lancaster 90
0 OriginalGriff 5,790
1 DamithSL 4,601
2 Maciej Los 4,012
3 Kornfeld Eliyahu Peter 3,480
4 Sergey Alexandrovich Kryukov 3,195


Advertise | Privacy | Mobile
Web04 | 2.8.141220.1 | Last Updated 6 Feb 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100