WPF重复元素

时间:2011-10-07 14:04:33

标签: wpf wpf-controls

我有一个UserControl是一个具有某些特征的按钮,我有一个窗口,其中有几个这些按钮处于“正常”样式。在同一个窗口,我已经定义了一个覆盖一些正常特征的样式,我想要一堆它们(有点像键盘布局)。我所拥有的是一个包含30行的UniformGrid:

<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>

其中唯一不变的是标记和内容值。什么是更好的方式来布置像这样重复的东西,其中Style和Click事件不必在每一行上?

3 个答案:

答案 0 :(得分:9)

更好的方法是在代码中创建一个数据对象,代表您在UI中需要的30个项目,例如:

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

(我相信你能想出一个更好的名字!)。然后创建30个项目并将它们设置为ItemsControl的ItemsSource:

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

您的ItemsControl有一个DataTemplate,用于呈现每个项目:

<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>

答案 1 :(得分:3)

我猜测ColinE的反应是他的头顶,我给了他一个+1来指示我正确的方向[谢谢],虽然它没有完全奏效。我最终得到的结果是:

在窗口的构造函数中,设置30条几乎相同的行:

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

然后,这个xaml(注意“Caption”是我们用户控件的属性,所以它不适合你):

<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>

答案 2 :(得分:2)

另一种选择(更多纯粹的xaml)解决方案是使用默认样式BasedOn命名样式,并为ClickEvent添加EventSetter:

<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>

对于遇到此答案的任何其他人的完整通用示例:

您现有的代码可能如下所示:

<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>

您可以将其更改为以下内容:

<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>