2009-04-13 8 views
22

मेरे पास एक क्रमबद्ध सूचीबॉक्स है और प्रत्येक आइटम की पंक्ति संख्या प्रदर्शित करने की आवश्यकता है। इस डेमो में मेरे पास एक नाम वर्ग संपत्ति वाला व्यक्ति वर्ग है। सूची बॉक्स नाम से क्रमबद्ध व्यक्तियों की एक सूची प्रदर्शित करता है। मैं पंक्ति संख्या सूची सूची के डेटामैप्लेट में कैसे जोड़ सकता हूं ???क्रमांकित सूचीबॉक्स

XAML:

<Window x:Class="NumberedListBox.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Height="300" Width="300"> 
    <ListBox 
     ItemsSource="{Binding Path=PersonsListCollectionView}" 
     HorizontalContentAlignment="Stretch"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <TextBlock Text="{Binding Path=Name}" /> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
</Window> 

कोड के पीछे:

using System; 
using System.Collections.ObjectModel; 
using System.Windows.Data; 
using System.Windows; 
using System.ComponentModel; 

namespace NumberedListBox 
{ 
    public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 

      Persons = new ObservableCollection<Person>(); 
      Persons.Add(new Person() { Name = "Sally"}); 
      Persons.Add(new Person() { Name = "Bob" }); 
      Persons.Add(new Person() { Name = "Joe" }); 
      Persons.Add(new Person() { Name = "Mary" }); 

      PersonsListCollectionView = new ListCollectionView(Persons); 
      PersonsListCollectionView.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending)); 

      DataContext = this; 
     } 

     public ObservableCollection<Person> Persons { get; private set; } 
     public ListCollectionView PersonsListCollectionView { get; private set; } 
    } 

    public class Person 
    { 
     public string Name { get; set; } 
    } 
} 

उत्तर

5

यह जाना चाहिए कि आप आरंभ:

http://weblogs.asp.net/hpreishuber/archive/2008/11/18/rownumber-in-silverlight-datagrid-or-listbox.aspx

यह कहना है कि वह सिल्वरलाइट के लिए है, लेकिन मैं नहीं दिख रहा है यह डब्ल्यूपीएफ के लिए क्यों काम नहीं करेगा। असल में, आप अपने डेटा में टेक्स्टब्लॉक बांधते हैं और वर्तमान आइटम के नंबर को आउटपुट करने के लिए कस्टम वैल्यू कनवर्टर का उपयोग करते हैं।

3

डेविड ब्राउन के लिंक में विचार एक मूल्य कनवर्टर का उपयोग करना था जो काम करता था। नीचे एक पूर्ण कामकाजी नमूना है। सूची बॉक्स में पंक्ति संख्याएं हैं और उन्हें नाम और आयु दोनों पर क्रमबद्ध किया जा सकता है।

XAML:

<Window x:Class="NumberedListBox.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:NumberedListBox" 
    Height="300" Width="300"> 

    <Window.Resources> 

     <local:RowNumberConverter x:Key="RowNumberConverter" /> 

     <CollectionViewSource x:Key="sortedPersonList" Source="{Binding Path=Persons}" /> 

    </Window.Resources> 

    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition /> 
      <RowDefinition Height="Auto"/> 
     </Grid.RowDefinitions> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition /> 
      <ColumnDefinition /> 
     </Grid.ColumnDefinitions> 
     <ListBox 
      Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" 
      ItemsSource="{Binding Source={StaticResource sortedPersonList}}" 
      HorizontalContentAlignment="Stretch"> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <StackPanel Orientation="Horizontal"> 
         <TextBlock 
          Text="{Binding Converter={StaticResource RowNumberConverter}, ConverterParameter={StaticResource sortedPersonList}}" 
          Margin="5" /> 
         <TextBlock Text="{Binding Path=Name}" Margin="5" /> 
         <TextBlock Text="{Binding Path=Age}" Margin="5" /> 
        </StackPanel> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 
     <Button Grid.Row="1" Grid.Column="0" Content="Name" Tag="Name" Click="SortButton_Click" /> 
     <Button Grid.Row="1" Grid.Column="1" Content="Age" Tag="Age" Click="SortButton_Click" /> 
    </Grid> 
</Window> 

कोड के पीछे:

using System; 
using System.Collections.ObjectModel; 
using System.Windows.Data; 
using System.Windows; 
using System.ComponentModel; 
using System.Windows.Controls; 

namespace NumberedListBox 
{ 
    public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 

      Persons = new ObservableCollection<Person>(); 
      Persons.Add(new Person() { Name = "Sally", Age = 34 }); 
      Persons.Add(new Person() { Name = "Bob", Age = 18 }); 
      Persons.Add(new Person() { Name = "Joe", Age = 72 }); 
      Persons.Add(new Person() { Name = "Mary", Age = 12 }); 

      CollectionViewSource view = FindResource("sortedPersonList") as CollectionViewSource; 
      view.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending)); 

      DataContext = this; 
     } 

     public ObservableCollection<Person> Persons { get; private set; } 

     private void SortButton_Click(object sender, RoutedEventArgs e) 
     { 
      Button button = sender as Button; 
      string sortProperty = button.Tag as string; 
      CollectionViewSource view = FindResource("sortedPersonList") as CollectionViewSource; 
      view.SortDescriptions.Clear(); 
      view.SortDescriptions.Add(new SortDescription(sortProperty, ListSortDirection.Ascending)); 

      view.View.Refresh(); 
     } 
    } 

    public class Person 
    { 
     public string Name { get; set; } 
     public int Age { get; set; } 
    } 
} 

मूल्य कनवर्टर:

using System; 
using System.Windows.Data; 

namespace NumberedListBox 
{ 
    public class RowNumberConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      CollectionViewSource collectionViewSource = parameter as CollectionViewSource; 

      int counter = 1; 
      foreach (object item in collectionViewSource.View) 
      { 
       if (item == value) 
       { 
        return counter.ToString(); 
       } 
       counter++; 
      } 
      return string.Empty; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 
    } 
} 
+12

उह, क्या यह एन^2 व्यवहार में नतीजा नहीं है? स्क्रीन पर प्रत्येक आइटम के लिए, मौजूदा आइटम इंडेक्स की अनुक्रमणिका खोजने के लिए सभी संभावित वस्तुओं पर पुनरावृत्ति करें। – Armentage

46

अंत में! यदि बेहतर तरीके से बेहतर तरीके से और अधिक संभवतः एक और तरीका मिल गया है। (Accessing an ItemsControl item as it is added भी देखें)

हम इस संपत्ति के लिए ItemsControl.AlternateIndex संपत्ति का दुरुपयोग करते हैं। मूल रूप से यह ListBox के भीतर अलग-अलग पंक्तियों को संभालने का इरादा है। ListBox में निहित मदों की राशि

<ListBox ItemsSource="{Binding Path=MyListItems}" 
     AlternationCount="{Binding Path=MyListItems.Count}" 
     ItemTemplate="{StaticResource MyItemTemplate}" 
... 
/> 

2. बाध्य करने के लिए (http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.alternationcount.aspx देख)

1. सेट AlternatingCount अपने DataTemplate AlternatingIndex को

<DataTemplate x:Key="MyItemTemplate" ... > 
    <StackPanel> 
     <Label Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplatedParent.(ItemsControl.AlternationIndex)}" /> 
     ... 
    </StackPanel> 
</DataTemplate> 

तो यह बिना काम करता है एक कनवर्टर, एक अतिरिक्त CollectionViewSource और स्रोत संग्रह के बिना सबसे महत्वपूर्ण रूप से क्रूर-बल-खोज के बिना।

+0

@yhw: धन्यवाद, एक समाधान मिला ... – Seven

+1

दोह! Silverlight में AlternationCount नहीं है। नीचे एक चांदी के प्रकाश समाधान पोस्ट किया गया। –

+0

मैं किसी और चीज पर फंस गया लेकिन समस्या हल हो गई, अच्छी नौकरी ब्रो +1 – Disposer

2

फिर भी एक और जवाब। मैंने उपरोक्त कोशिश की, जो डब्ल्यूपीएफ (AlternationCount समाधान) में काम करता है, लेकिन मुझे सिल्वरलाइट के लिए कोड चाहिए, इसलिए मैंने निम्नलिखित किया। यह अन्य ब्रूट फोर्स विधि की तुलना में अधिक सुरुचिपूर्ण है।

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:RowNumber" x:Name="userControl" 
    x:Class="RowNumber.MainPage" Width="640" Height="480"> 
<Grid x:Name="LayoutRoot" Background="White"> 
    <ListBox ItemsSource="{Binding Test, ElementName=userControl}"> 
    <ListBox.Resources> 
     <local:ListItemIndexConverter x:Key="IndexConverter" /> 
    </ListBox.Resources> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Width="30" 
        Text="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Converter={StaticResource IndexConverter}}" /> 
       <TextBlock Text="{Binding}" /> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
    </ListBox> 
</Grid> 
</UserControl> 

और

using System; 
    using System.Collections.Generic; 
    using System.Globalization; 
    using System.Linq; 
    using System.Windows.Controls; 
    using System.Windows.Controls.Primitives; 
    using System.Windows.Data; 

    namespace RowNumber 
    { 
    public class ListItemIndexConverter : IValueConverter 
    { 
     // Value should be ListBoxItem that contains the current record. RelativeSource={RelativeSource AncestorType=ListBoxItem} 
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      var lbi = (ListBoxItem)value; 
      var listBox = lbi.GetVisualAncestors().OfType<ListBox>().First(); 
      var index = listBox.ItemContainerGenerator.IndexFromContainer(lbi); 
      // One based. Remove +1 for Zero based array. 
      return index + 1; 
     } 
     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } 
    } 
    public partial class MainPage : UserControl 
    { 
     public MainPage() 
     { 
      // Required to initialize variables 
      InitializeComponent(); 
     } 
     public List<string> Test { get { return new[] { "Foo", "Bar", "Baz" }.ToList(); } } 
    } 
    } 

यह बाध्यकारी RelativeSource की शुरूआत के साथ सिल्वरलाइट 5 में हाल में उपलब्ध है पीछे।

-1

क्यों न केवल सूची बॉक्स की संपत्ति गिनने के लिए बाध्यकारी।

<ListView x:Name="LstFocusImageDisplayData" 

          > 
        <ListView.ItemTemplate> 
         <DataTemplate> 
          <GroupBox Header="Item Count"> 
           <DockPanel> 
            <TextBlock Text="{Binding ElementName=LstFocusImageDisplayData, Path=Items.Count, Mode=OneTime}" /> 
           </DockPanel> 
          </GroupBox> 

         </DataTemplate> 
        </ListView.ItemTemplate> 
       </ListView> 
संबंधित मुद्दे