WPF repeating elements

后端 未结 3 665
执念已碎
执念已碎 2021-02-09 21:56

I have a UserControl that is a button, with certain characteristics, and I have a window that has several of these buttons in their \"normal\" style. On this same window, I hav

相关标签:
3条回答
  • 2021-02-09 22:36

    I guessed that ColinE's response was off the top of his head, and I gave him a +1 for pointing me in the right direction [THANKS], although it didn't exactly work. What I ended up with was close:

    In the constructor for the window, to set up the 30 almost-identical lines:

    var numberButtons = Enumerable.Range( 1, 30 )
        .Select( r => new KeyValuePair<string,string>( r.ToString( ), r.ToString( ) ) )
        .ToList( );
    numberButtonItems.ItemsSource = numberButtons;
    

    Then, this xaml (note that "Caption" is a property of our user control, so it won't work for you):

    <ItemsControl Grid.Row="1" x:Name="numberButtonItems">
        <ItemsControl.ItemsPanel>
        <!-- specify the panel that is the container for your items -->
            <ItemsPanelTemplate>
                 <UniformGrid Rows="4" Columns="10" HorizontalAlignment="Left" />
            </ItemsPanelTemplate>
       </ItemsControl.ItemsPanel>
       <!-- specify the template used to render each item -->
       <ItemsControl.ItemTemplate>
            <DataTemplate>
                 <wft:TouchButton Style="{StaticResource smallButtonStyle}"
                      Click="TouchButton_Click"
                      Tag="{Binding Key}"
                      Caption="{Binding Value}"/>
            </DataTemplate>
       </ItemsControl.ItemTemplate>
     </ItemsControl>
    
    0 讨论(0)
  • 2021-02-09 22:39

    A better way would be to create a data-object in code that represents the 30 items that you want in your UI, for example:

    class DataObject
    {
      string Tag {get;set;}
      string Content {get;set;}
    }
    

    (I am sure you can come up with a better name than that!). Then create your 30 items and set them as the ItemsSource of an ItemsControl:

    List<DataObject> myObjects = new List<DataObject>();
    // populate here
    itemsControl.ItemsSource = myObjects
    

    Your ItemsControl has a DataTemplate that is used to render each item:

    <ItemsControl x:Name="itemsControl">
      <!-- specify the panel that is the container for your items -->
      <ItemsControl.ItemPanelTemplate>
        <ItemPanelTemplate>
          <UniformGrid/>
        </ItemPanelTemplate>
      </ItemsControl.ItemPanelTemplate>
      <!-- specify the template used to render each item -->
      <ItemsControl.ItemTemplate>
        <DataTemplate>
           <wft:TouchButton Style="{StaticResource smallButtonStyle}"
                            Click="TouchButton_Click"
                            Tag="{Binding Tag}"/
                            Content="{Binding Content}">
        </DataTemplate>
      </ItemsControl.ItemTemplate>
    </ItemsControl>
    
    0 讨论(0)
  • 2021-02-09 22:45

    An alternative (more of a pure xaml) solution would be to use a default style BasedOn your named style, and adding an EventSetter for the ClickEvent:

    <UniformGrid>
        <UniformGrid.Resources>
            <Style TargetType="{x:Type wft:TouchButton}" BasedOn="{StaticResource smallButtonStyle}">
                <EventSetter Event="Click" Handler="chButton_Click" />
            </Style>
        </UniformGrid.Resources>
        <wft:TouchButton Tag="1">1</wft:TouchButton>
        <wft:TouchButton Tag="2">2</wft:TouchButton>
        <wft:TouchButton Tag="3">3</wft:TouchButton>
    </UniformGrid>
    

    A complete generic example for anyone else who runs across this answer:

    Your existing code might look like this:

    <Window x:Class="TestWPF.MainWindow"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                Title="MainWindow">
        <Window.Resources>
            <Style x:Key="myButtonStyle" TargetType="{x:Type Button}">
                <Setter Property="Background" Value="Red" />
            </Style>
        </Window.Resources>
        <Grid>
            <StackPanel>
                <Button Style="{StaticResource myButtonStyle}" Content="1" Click="Button_Click" />
                <Button Style="{StaticResource myButtonStyle}" Content="2" Click="Button_Click" />
                <Button Style="{StaticResource myButtonStyle}" Content="3" Click="Button_Click" />
                <Button Style="{StaticResource myButtonStyle}" Content="4" Click="Button_Click" />
                <Button Style="{StaticResource myButtonStyle}" Content="5" Click="Button_Click" />
                <Button Style="{StaticResource myButtonStyle}" Content="6" Click="Button_Click" />
            </StackPanel>
        </Grid>
    </Window>
    

    And you can change it to the following:

    <Window x:Class="TestWPF.MainWindow"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                Title="MainWindow">
        <Window.Resources>
            <Style x:Key="myButtonStyle" TargetType="{x:Type Button}">
                <Setter Property="Background" Value="Red" />
            </Style>
        </Window.Resources>
        <Grid>
            <StackPanel>
                <StackPanel.Resources> <!-- Adding style below will apply to all Buttons in the stack panel -->
                    <Style TargetType="{x:Type Button}" BasedOn="{StaticResource myButtonStyle}">
                        <EventSetter Event="Click" Handler="Button_Click" />
                    </Style>
                </StackPanel.Resources>
                <Button Content="1" />
                <Button Content="2" />
                <Button Content="3" />
                <Button Content="4" />
                <Button Content="5" />
                <Button Content="6" />
            </StackPanel>
        </Grid>
    </Window>
    
    0 讨论(0)
提交回复
热议问题