2011-01-12 5 views
0

저는 .NET 프로그래밍을 가르치고 있습니다. 현재 WPF에서 태그 클라우드 컨트롤을 작성하려고합니다. 목표는 첫 번째 목록 상자가 "ContactLists"목록을 표시하고 두 번째 목록 상자가 ContactLists와 연관된 "레이블"(또는 태그)을 표시하는 창에 2 개의 목록 상자를 갖는 것입니다. 레이블의 목적은 IValueConverter를 사용하여 itemCount에 글꼴 크기를 바인딩하는 것입니다. 따라서 내 컬렉션에 여러 번 나타나는 특정 레이블이 있으면 레이블 목록 상자에 더 큰 글꼴로 표시됩니다. 또한 DB2 데이터베이스에서 내 컨트롤을 채우는 중입니다.IValueConverter 데이터 바인딩

나는 정확한 목록 상자에 ContactLists와 Labels를 표시하고 있으므로 바인딩에 문제가 있습니다. 나는 튜토리얼에서 가져간 컨버터 클래스를 사용하고 있으며 누군가가 나를 도와 줄 수 있는지 궁금해하고있다. 많은 감사 - 벤

속성

public class Label 
{ 
    public int LabelID { get; set; } 
    public string LabelName { get; set; } 

} 

ContactListClass

public class ContactList  
    {   
     public string ContactListName { get; set; } 
     public List<Label> Labels { get; set; } 

    } 

변환기

public class CountToFontSizeConverter : IValueConverter 
    { 
     #region IValueConverter Members 

     public object Convert(object value, Type targetType, 
      object parameter, CultureInfo culture) 
     { 
      const int minFontSize = 6; 
      const int maxFontSize = 38; 
      const int increment = 3; 
      int count = (int)value; 
      return ((minFontSize + count + increment) < maxFontSize) ? 
        (minFontSize + count + increment)    : 
        maxFontSize; 
     } 

     public object ConvertBack(object value, Type targetType, 
      object parameter, CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 
     #endregion 
    } 

창로드 이벤트

private void Window_Loaded(object sender, System.Windows.RoutedEventArgs e) 
    { 
     //TODO: Add event handler implementation here. 
     ListCollectionView lcv = new ListCollectionView(myLabels); 

     lcv.GroupDescriptions.Add(new PropertyGroupDescription("LabelName")); 

     tagsList.ItemsSource = lcv.Groups;      
    } 

XAML은

<Window.Resources> 
    <local:CountToFontSizeConverter x:Key="CountToFontSizeConverter"/> 

    <Style x:Key="tagsStyle" TargetType="{x:Type ListBox}"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type ListBox}"> 
        <Grid> 
         <Border x:Name="Border" 
           BorderBrush="{TemplateBinding BorderBrush}" 
           BorderThickness="{TemplateBinding BorderThickness}"/> 
          <WrapPanel Orientation="Horizontal" 
             Margin="2" 
             IsItemsHost="true" 
             Background="#FFFCF6F6"/> 
        </Grid> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

    <DataTemplate x:Key="ContactsTemplate"> 
    <WrapPanel> 
     <TextBlock TextWrapping="Wrap" 
         Text="{Binding ContactListName, Mode=Default}"/> 
    </WrapPanel> 
    </DataTemplate> 

    <DataTemplate x:Key="TagsTemplate"> 
    <WrapPanel> 
     <TextBlock Text="{Binding LabelName, Mode=Default}" 
         TextWrapping="Wrap" 
         FontSize="{Binding ItemCount, 
            Converter={StaticResource CountToFontSizeConverter}, 
            Mode=Default}" 
         Foreground="#FF0D0AF7"/> 
    </WrapPanel> 
    </DataTemplate> 
</Window.Resources> 

<Grid x:Name="LayoutRoot" Background="#FFCBD5E6"> 
    <ListBox x:Name="contactsList" 
      SelectionMode="Multiple" 
      Margin="7,8,0,7" 
      ItemsSource="{Binding ContactLists, Mode=Default}" 
      ItemTemplate="{DynamicResource ContactsTemplate}" 
      HorizontalAlignment="Left" 
      Width="254"/> 

    <ListBox x:Name="tagsList" 
      Margin="293,8,8,8" 
      ItemsSource="{Binding Labels, Mode=Default}" 
      ItemTemplate="{StaticResource TagsTemplate}" 
      Style="{StaticResource tagsStyle}" /> 
</Grid> 
+0

FYI - 귀하의 질문을 다시 읽을 수 있도록 다시 형식화했습니다. 처음에는이 모든 것들이 거기에 있다는 것을 몰랐습니다. 앞으로는 읽을 수있는 형식으로 게시물을 올리면 답을 얻게 될 가능성이 훨씬 더 높습니다. 일반적으로 큰 덩어리가있는 곳에 질문을 건너 뜁니다. 이 코드가 자신의 코드에서 복사하여 붙여 넣기했다면, 거기에 형식을 지정하는 것이 겸허하게 제안되었습니다. 그것은 코드 soooooo 훨씬 쉽게 유지합니다. –

답변

0

당신은 당신의 문제를 매우 정확하지 않습니다, 그래서 난 그냥 몇 가지 의견을 침하기 위하여려고하고있다.

문제는 모델 (Label 및 ContactList)이 INotifyPropertyChanged를 구현하지 않으므로 WPF가 그러한 속성이 변경된 것을 알기 어렵다는 것입니다. 그러나 런타임에 값을 변경하지 않더라도 문제가되지는 않습니다.

또한 NotImplementedException을 던지는 대신 Binding.DoNothing을 반환하는 것이 좋습니다.

모드 = 기본값을 도처에서 제거 할 수도 있지만 필수는 아닙니다.

태그가 들어있는 목록 상자에 바인딩되어있는 것을 확인했습니다. 하지만 왜 당신은 연락처 목록을 바인딩하지 않는거야? 코드를 통해 모두 설정하거나 바인딩을 사용해야하며 바인딩을 선호합니다.

실제 문제에 대한 자세한 내용을 제공 할 수 있다면 더 잘 도와 줄 수 있습니다.

+0

답변을 보내 주셔서 감사합니다. 막연한 질문에 사과드립니다. 그래서 런타임에 값을 변경하지 않고 있습니다. 그래서 INotifyPropertyChanged를 구현하지 않았습니다. 실제 문제는 내 tagsTemplate의 LabelName을 내 컬렉션에 표시되는 횟수만큼 바인딩하는 방법입니다. – Ben

0

벤, 아직도 내가 직면 한 문제에 대해 확신하지 못합니다.

코드를 실행할 때 정확히 어떻게됩니까? 레이블 이름의 글꼴 크기가 변경 되었습니까?

는 ItemsSource = "{바인딩 레이블, 모드 = 기본}"

- 당신은 당신의 XAML 모두에서 tagsList 및 코드 ItemsSource를 설정하는

1 -

문제 난 당신의 코드를 볼 수 있습니다

tagsList.ItemsSource = lcv.Groups;

2 어디서나 정의 된 ItemCount 속성이 표시되지 않습니까?

3 FontSize는 double 값이므로 변환기는 int가 아닌 double 값을 반환해야합니다.

4 '라벨'목록은 관찰 할 수있는 컬렉션이어야합니다 (런타임에 항목을 추가하거나 삭제할 수있는 경우).

관련 문제