2011-10-07 4 views
5

특정 특성이있는 단추 인 UserControl이 있고 "정상"스타일로 여러 단추가있는 창이 있습니다. 이 동일한 창에서, 나는 정상적인 특성의 일부를 오버라이드하는 스타일을 정의했고, 나는 그들 (키보드 레이아웃과 같은 종류)을 원한다. 내가 가진 것은 다음과 같은 30 줄의 UniformGrid이다.WPF 반복 요소

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

여기서 유일한 변경 사항은 태그와 내용 값이다. 스타일과 클릭 이벤트가 모든 라인에있을 필요가없는 이와 같은 반복적 인 것을 레이아웃하는 더 좋은 방법은 무엇입니까?

답변

3

을 그의 머리 꼭대기에서, 그리고 나는 그에게 정확한 방향으로 나를 가리키기 위해 +1을 주었다. [감사합니다], 정확하게 작동하지는 않았지만. 내가 함께 결국은 가까이 : 윈도우의 생성자에서

, 30 거의-동일한 라인 설정 :

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

그런 다음이 XAML은 ("캡션"의 속성입니다 있습니다 당신을 위해 작동하지 않도록 우리의 사용자 제어) : 용액) 순수 XAML의

<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> 
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을 가지고 : 나는 ColinE의 응답이 떨어져 것을 짐작

<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

"첨부 가능 속성 'ItemPanelTemplate'이 (가) ItemsControl 유형에서 없습니다. '가 나타납니다. 나는 당신을 너무 문자 그대로 찍었을지도 모르지만, (1) ItemsControl Name을 변경하고, (2) UniformGrid의 rows/columns 속성을 채우며, (3) Tag와 Content 구문을 고쳤습니다. [추신. 나는 닷넷 3.5에있다.] –

+0

위의 코드는 메모리에서 나온 것이므로 오타가있을 수있다. 나는 그것이 대신 ItemsPanelTemplate일지도 모른다라고 생각한다. – ColinE

2

대안 (더 명명 된 스타일 기본 스타일 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> 
+0

나는 이것을 정확히 선택하지 않았다. 왜냐하면 나는 거의 똑같은 30 개의 라인을 가지려고 노력했기 때문이다.하지만 +1은 순수한 xaml로 유지하고 StackPanel 레벨에서 리소스를 보여 다른 버튼을 남겨둔다. –

+0

이 방법으로 정확하게 스타일에 대한 반복을 방지하는 방법과 각 줄을 클릭하는 질문에 정확히 대답했습니다. –

+0

@Kelly Cline - 문제 없습니다 ...나는 당신을 위해 좋은 해결책을 찾을 수있어서 다행입니다. 나는 누군가가이 포스트를 우연히 만날 경우이 답변을 추가 할 것이라고 생각했습니다. – Scott