开发者

WPF repeating elements

开发者 https://www.devze.com 2023-04-11 16:57 出处:网络
I have a UserControl th开发者_JAVA技巧at 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 have defined

I have a UserControl th开发者_JAVA技巧at 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 have defined a style that overrides some of the normal characteristics, and I want a bunch of them (sort of like a keyboard layout). What I have is a UniformGrid with 30 lines like this:

<wft:TouchButton Style="{StaticResource smallButtonStyle}" Click="TouchButton_Click" Tag="1">1</wft:TouchButton>

<wft:TouchButton Style="{StaticResource smallButtonStyle}" Click="TouchButton_Click" Tag="2">2</wft:TouchButton>

<wft:TouchButton Style="{StaticResource smallButtonStyle}" Click="TouchButton_Click" Tag="3">3</wft:TouchButton>

where the only thing changing from line to line is the Tag and Content values. What is a better way to lay out something repetitive like this, where the Style and Click events do not have to be on every line?


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>


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>


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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号