কলাম-শিরোলেখ ক্লিক করে ডাব্লুপিএফ তালিকাভিউ / গ্রিডভিউ সাজানোর সেরা উপায়?


84

আছে প্রচুর ইন্টারনেট WPF থেকে এই আপাতদৃষ্টিতে খুব-মৌলিক ভ্রান্তি পূরণ করার চেষ্টা উপর সমাধান। "সেরা" উপায়টি কী হবে তা নিয়ে আমি সত্যিই বিভ্রান্ত। উদাহরণস্বরূপ ... আমি চাই সাজানোর দিক নির্দেশ করতে কলামের শিরোনামটিতে কিছুটা উপরে / নীচে তীর থাকা উচিত। এটি করার জন্য স্পষ্টতই 3 টি বিভিন্ন উপায়ে রয়েছে, কিছু কোড ব্যবহার করে, কিছু মার্কআপ ব্যবহার করে, কিছু মার্কআপ-প্লাস-কোড ব্যবহার করে এবং সমস্ত হ্যাকের মতো মনে হয়।

এর আগে কি কেউ এই সমস্যায় পড়েছে এবং এর সমাধান পেয়েছেন যে তারা এতে সম্পূর্ণ খুশি? উদ্ভট বলে মনে হয় যে ডাব্লুপিএফ থেকে এই জাতীয় বেসিক উইন্ডোর্মস কার্যকারিতাটি অনুপস্থিত এবং এটি হ্যাক করা দরকার।


কীভাবে স্বীকৃতি পেতে ব্যবহার করা যায় সে সম্পর্কে উপরের প্রশ্নের উত্তরে। এক্সএমএল ডকুমেন্টের শীর্ষে নেমস্পেসে এক্সএমএনএলএস: ইউজার = "ক্লিটার-নেমস্পেস: ডাব্লুপিএফ.উটিল" যুক্ত করুন
মেলডো

সম্ভব হলে .. ডাটাগ্রিড ব্যবহার করুন।
অভিজিৎ নাগরে

উত্তর:


22

এটি সমস্ত কিছুর উপর নির্ভর করে, আপনি যদি ডাব্লুপিএফ টুলকিট থেকে ডেটাগ্রিড ব্যবহার করছেন তবে সেখানে একটি বিল্ট ইন সাজ্ট রয়েছে, এমনকি একটি বহু-কলামের বাছাইও রয়েছে যা খুব দরকারী। এখানে আরও দেখুন:

ভিনসেন্ট সিবলস ব্লগ

বিকল্পভাবে, আপনি যদি আলাদা কোনও নিয়ন্ত্রণ ব্যবহার করেন যা বাছাই সমর্থন করে না, আমি নিম্নলিখিত পদ্ধতিগুলি সুপারিশ করব:

লি গাওর কাস্টম বাছাই

অনুসরণ করেছেন:

লি গাওর দ্রুত বাছাই


111

আমি স্বয়ংক্রিয়ভাবে একটি বাছাই করতে সংযুক্ত বৈশিষ্ট্যের একটি সেট লিখেছি GridView, আপনি এটি এখানে পরীক্ষা করে দেখতে পারেন । এটি উপরের / নীচে তীরটি পরিচালনা করে না তবে এটি সহজেই যুক্ত হতে পারে।

<ListView ItemsSource="{Binding Persons}"
          IsSynchronizedWithCurrentItem="True"
          util:GridViewSort.AutoSort="True">
    <ListView.View>
        <GridView>
            <GridView.Columns>
                <GridViewColumn Header="Name"
                                DisplayMemberBinding="{Binding Name}"
                                util:GridViewSort.PropertyName="Name"/>
                <GridViewColumn Header="First name"
                                DisplayMemberBinding="{Binding FirstName}"
                                util:GridViewSort.PropertyName="FirstName"/>
                <GridViewColumn Header="Date of birth"
                                DisplayMemberBinding="{Binding DateOfBirth}"
                                util:GridViewSort.PropertyName="DateOfBirth"/>
            </GridView.Columns>
        </GridView>
    </ListView.View>
</ListView>

8
থমাসকে ধন্যবাদ, বাছাইয়ের সমস্যার সমাধান আপনার সমাধানটি মার্জিত, ব্যবহারযোগ্য সহজ এবং খুব নমনীয়। অন্য কথায়: নিখুঁত! অন্যদের জন্য পরামর্শ: 1) টমাসের নিবন্ধে লিঙ্কযুক্ত আপডেট করা সংস্করণ ব্যবহার করুন এবং 2) মন্তব্যগুলিতে অ্যালেক্সের প্রিটিয়ার গ্লাইফ সংস্করণটি ব্যবহার করুন।
হেলিজ ক্লিন

আমি ডাব্লুপিএফ-এ নতুন এবং এই "ব্যবহার" বিটটি বেশ বুঝতে পারি না। কি রেফারেন্সিং? সম্পাদনা: এনএম ... "ভিউ সোর্স" নামে একটি ছোট্ট লিঙ্কটি ছিল যা এখনই আমার দিকে ঝাঁপিয়ে পড়ে না। এটি শ্রেণীর জন্য উত্স কোডটি প্রসারিত করে
13

আমি খুব পছন্দ করি! আমি আইটেমগুলি গতিশীলভাবে যুক্ত / অপসারণ করছি এবং এটি অর্ডার পরিবর্তন না করে দুর্দান্ত কাজ করে। তবে আমি কীভাবে বাছাইয়ের জন্য প্রাথমিক অবস্থা সেট করতে পারি? CollectionViewSource.GetDefaultView(MyList.ItemsSource).SortDescriptions.Add(new SortDescription("Number", ListSortDirection.Ascending));কাজ করে না
জি

@ জিৎ, এটি কাজ করা উচিত, তবে এটি গ্লাফ বাছাই করে না ... প্রাথমিক অর্ডার সেট করার কোনও উপায় আমি প্রয়োগ করি নি, তবে আপনি সর্বদা আমার কোডটি সংশোধন করার চেষ্টা করতে পারেন;)
থমাস লেভেস্ক

আমার দোষ - এটি পুরোপুরি কাজ করে! (আমি ক্লিয়ারিং পরিবর্তে একটি নতুন তালিকা instanced, তাই SortDescriptions resettet ছিল না) দুঃখিত
জী

23

এমএসডিএন এর আপ / ডাউন গ্লাইফগুলি সহ কলামগুলিতে বাছাই করার সহজ উপায় রয়েছে । উদাহরণটি সম্পূর্ণ নয়, যদিও - তারা গ্লাইফগুলির জন্য ডেটা টেম্পলেটগুলি কীভাবে ব্যবহার করবেন তা ব্যাখ্যা করে না। নীচে আমার লিস্টভিউয়ের সাথে কাজ করতে পেয়েছি। এটি কাজ করে। নেট 4।

আপনার তালিকাভিউতে, আপনাকে গ্রিডভিউ কলাম কলাম হিডারে ক্লিক করার জন্য একটি ইভেন্ট হ্যান্ডলার নির্দিষ্ট করতে হবে। আমার তালিকাভিউটি দেখতে এমন দেখাচ্ছে:

<ListView Name="results" GridViewColumnHeader.Click="results_Click">
    <ListView.View>
        <GridView>
            <GridViewColumn DisplayMemberBinding="{Binding Path=ContactName}">
                <GridViewColumn.Header>
                    <GridViewColumnHeader Content="Contact Name" Padding="5,0,0,0" HorizontalContentAlignment="Left" MinWidth="150" Name="ContactName" />
                </GridViewColumn.Header>
            </GridViewColumn>
            <GridViewColumn DisplayMemberBinding="{Binding Path=PrimaryPhone}">
                <GridViewColumn.Header>
                    <GridViewColumnHeader Content="Contact Number" Padding="5,0,0,0" HorizontalContentAlignment="Left" MinWidth="150" Name="PrimaryPhone"/>
                </GridViewColumn.Header>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

আপনার কোড পিছনে, বাছাই পরিচালনা করতে কোড সেট আপ করুন:

// Global objects
BindingListCollectionView blcv;
GridViewColumnHeader _lastHeaderClicked = null;
ListSortDirection _lastDirection = ListSortDirection.Ascending;

// Header click event
void results_Click(object sender, RoutedEventArgs e)
{
    GridViewColumnHeader headerClicked =
    e.OriginalSource as GridViewColumnHeader;
    ListSortDirection direction;

    if (headerClicked != null)
    {
    if (headerClicked.Role != GridViewColumnHeaderRole.Padding)
    {
        if (headerClicked != _lastHeaderClicked)
        {
            direction = ListSortDirection.Ascending;
        }
        else
        {
            if (_lastDirection == ListSortDirection.Ascending)
            {
                direction = ListSortDirection.Descending;
            }
            else
            {
                direction = ListSortDirection.Ascending;
            }
        }

        string header = headerClicked.Column.Header as string;
        Sort(header, direction);

        if (direction == ListSortDirection.Ascending)
        {
            headerClicked.Column.HeaderTemplate =
              Resources["HeaderTemplateArrowUp"] as DataTemplate;
        }
        else
        {
            headerClicked.Column.HeaderTemplate =
              Resources["HeaderTemplateArrowDown"] as DataTemplate;
        }

        // Remove arrow from previously sorted header
        if (_lastHeaderClicked != null && _lastHeaderClicked != headerClicked)
        {
            _lastHeaderClicked.Column.HeaderTemplate = null;
        }

        _lastHeaderClicked = headerClicked;
        _lastDirection = direction;
    }
}

// Sort code
private void Sort(string sortBy, ListSortDirection direction)
{
    blcv.SortDescriptions.Clear();
    SortDescription sd = new SortDescription(sortBy, direction);
    blcv.SortDescriptions.Add(sd);
    blcv.Refresh();
}

এবং তারপরে আপনার এক্সএএমএল-এ, আপনি বাছাই করার পদ্ধতিতে নির্দিষ্ট করেছেন এমন দুটি ডেটা টেম্পলেট যুক্ত করতে হবে:

<DataTemplate x:Key="HeaderTemplateArrowUp">
    <DockPanel LastChildFill="True" Width="{Binding ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type GridViewColumnHeader}}}">
        <Path x:Name="arrowUp" StrokeThickness="1" Fill="Gray" Data="M 5,10 L 15,10 L 10,5 L 5,10" DockPanel.Dock="Right" Width="20" HorizontalAlignment="Right" Margin="5,0,5,0" SnapsToDevicePixels="True"/>
        <TextBlock Text="{Binding }" />
    </DockPanel>
</DataTemplate>

<DataTemplate x:Key="HeaderTemplateArrowDown">
    <DockPanel LastChildFill="True" Width="{Binding ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type GridViewColumnHeader}}}">
        <Path x:Name="arrowDown" StrokeThickness="1" Fill="Gray"  Data="M 5,5 L 10,10 L 15,5 L 5,5" DockPanel.Dock="Right" Width="20" HorizontalAlignment="Right" Margin="5,0,5,0" SnapsToDevicePixels="True"/>
        <TextBlock Text="{Binding }" />
    </DockPanel>
</DataTemplate>

সত্য DockPanelদিয়ে LastChildFillসেটটি ব্যবহার করা শিরোনামের ডানদিকে গ্লাইফ রাখবে এবং লেবেলটি বাকী স্থান পূরণ করবে। আমি আবদ্ধ DockPanelকরার প্রস্থ ActualWidthএর GridViewColumnHeaderকারণ আমার কলাম কোন প্রস্থ, যা বিষয়বস্তু তাদের স্বফিট দেয় না। আমি MinWidthকলামগুলিতে সেট করেছি যদিও, গ্লিফটি কলামের শিরোনামটি কভার না করে। TextBlock Textএকটি খালি বাঁধাই যা প্রদর্শন কলামের নামের শিরোলেখে নির্দিষ্ট সেট করা হয়।


4
এটি এক্সএএমএল-তে কোথায় ডেটা টেম্পলেটগুলি গ্রিড রাখবে তা সুনির্দিষ্ট করে না?

4
@ মার্ক এটি আপনাকে সাহায্য করতে সম্ভবত খুব দেরী হয়েছে, তবে টেমপ্লেটগুলি মূল উপাদানটির সংস্থানগুলিতে রাখা উচিত, সাধারণত <Window.Resources>বা <UserControl.Resources>। এইচটিএইচএস;)
সিটিপ্রেবি

4
@ সিপিটিরোবি হাই .. আমার জন্য, যেহেতু ব্লকভিটি আরম্ভ করা হয়নি, এটি একটি নাল রেফারেন্স ব্যতিক্রম দেয় ... সুতরাং এই কোডটি কারও পক্ষে কীভাবে কাজ করবে?
জে নিরগুদকর

@ জয়নিরিগুদকার আমি এর লেখক নই, জ্যারেড হারলি। তবে আমি আপনাকে বলতে পারি যে ব্লকভিটি হ'ল তিনি তার তালিকাভিউয়ের আইটেমসোর্স হিসাবে ব্যবহার করছেন। আপনাকে একই জিনিস করতে হবে না। তিনি আইটিএসসোর্স মোকাবেলার বিকল্প পদ্ধতির জন্য যে এমএসডিএন লিঙ্কটি সরবরাহ করেছিলেন তা ক্লিক করুন।
সিটিপিআরবি

4
এমএসডিএন উদাহরণ ধরে নিয়েছে যে headerClicked.Column.Header(যা শিরোনাম পাঠ্য) সমান (headerClicked.Column.DisplayMemberBinding as Binding).Path.Path(যা বাধ্যতামূলক পথ)। শিরোনাম পাঠ্যে বাছাইয়ের কাজ হয় না। খুব অদ্ভুত.
ক্রিস

5

আমি এমভিভিএম ব্যবহার করি, তাই থমাসকে রেফারেন্স হিসাবে ব্যবহার করে আমি নিজের কিছু সংযুক্ত বৈশিষ্ট্য তৈরি করেছি। আপনি যখন হেডারে ক্লিক করেন তখন আরোহণ এবং উতরাইয়ের মধ্যে টগল করে এমন সময়ে এটি একটি কলামে বাছাই করে। প্রথম কলামটি ব্যবহার করে এটি শুরু থেকেই সাজায়। এবং এটি উইন 7/8 স্টাইলের গ্লিফগুলি দেখায়।

সাধারণত, আপনাকে যা করতে হবে তা হ'ল মূল সম্পত্তিটিকে সত্য হিসাবে সেট করা (তবে আপনাকে স্পষ্টভাবে গ্রিডভিউ কলামহিডারদের ঘোষণা করতে হবে):

<Window xmlns:local="clr-namespace:MyProjectNamespace">
  <Grid>
    <ListView local:App.EnableGridViewSort="True" ItemsSource="{Binding LVItems}">
      <ListView.View>
        <GridView>
          <GridViewColumn DisplayMemberBinding="{Binding Property1}">
            <GridViewColumnHeader Content="Prop 1" />
          </GridViewColumn>
          <GridViewColumn DisplayMemberBinding="{Binding Property2}">
            <GridViewColumnHeader Content="Prop 2" />
          </GridViewColumn>
        </GridView>
      </ListView.View>
    </ListView>
  </Grid>
<Window>

আপনি যদি প্রদর্শনটির চেয়ে আলাদা কোনও সম্পত্তি বাছাই করতে চান তবে আপনাকে এটি ঘোষণা করতে হবে:

<GridViewColumn DisplayMemberBinding="{Binding Property3}"
                local:App.GridViewSortPropertyName="Property4">
    <GridViewColumnHeader Content="Prop 3" />
</GridViewColumn>

সংযুক্ত বৈশিষ্ট্যের জন্য কোডটি এখানে, আমি অলস হতে এবং সরবরাহিত অ্যাপ্লিকেশনগুলিতে রাখতে চাই like

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data.
using System.Windows.Media;
using System.Windows.Media.Media3D;

namespace MyProjectNamespace
{
  public partial class App : Application
  {
      #region GridViewSort
      public static DependencyProperty GridViewSortPropertyNameProperty =
          DependencyProperty.RegisterAttached(
              "GridViewSortPropertyName", 
              typeof(string), 
              typeof(App), 
              new UIPropertyMetadata(null)
          );

      public static string GetGridViewSortPropertyName(GridViewColumn gvc)
      {
          return (string)gvc.GetValue(GridViewSortPropertyNameProperty);
      }

      public static void SetGridViewSortPropertyName(GridViewColumn gvc, string n)
      {
          gvc.SetValue(GridViewSortPropertyNameProperty, n);
      }

      public static DependencyProperty CurrentSortColumnProperty =
          DependencyProperty.RegisterAttached(
              "CurrentSortColumn", 
              typeof(GridViewColumn), 
              typeof(App), 
              new UIPropertyMetadata(
                  null, 
                  new PropertyChangedCallback(CurrentSortColumnChanged)
              )
          );

      public static GridViewColumn GetCurrentSortColumn(GridView gv)
      {
          return (GridViewColumn)gv.GetValue(CurrentSortColumnProperty);
      }

      public static void SetCurrentSortColumn(GridView gv, GridViewColumn value)
      {
          gv.SetValue(CurrentSortColumnProperty, value);
      }

      public static void CurrentSortColumnChanged(
          object sender, DependencyPropertyChangedEventArgs e)
      {
          GridViewColumn gvcOld = e.OldValue as GridViewColumn;
          if (gvcOld != null)
          {
              CurrentSortColumnSetGlyph(gvcOld, null);
          }
      }

      public static void CurrentSortColumnSetGlyph(GridViewColumn gvc, ListView lv)
      {
          ListSortDirection lsd;
          Brush brush;
          if (lv == null)
          {
              lsd = ListSortDirection.Ascending;
              brush = Brushes.Transparent;
          }
          else
          {
              SortDescriptionCollection sdc = lv.Items.SortDescriptions;
              if (sdc == null || sdc.Count < 1) return;
              lsd = sdc[0].Direction;
              brush = Brushes.Gray;
          }

          FrameworkElementFactory fefGlyph = 
              new FrameworkElementFactory(typeof(Path));
          fefGlyph.Name = "arrow";
          fefGlyph.SetValue(Path.StrokeThicknessProperty, 1.0);
          fefGlyph.SetValue(Path.FillProperty, brush);
          fefGlyph.SetValue(StackPanel.HorizontalAlignmentProperty, 
              HorizontalAlignment.Center);

          int s = 4;
          if (lsd == ListSortDirection.Ascending)
          {
              PathFigure pf = new PathFigure();
              pf.IsClosed = true;
              pf.StartPoint = new Point(0, s);
              pf.Segments.Add(new LineSegment(new Point(s * 2, s), false));
              pf.Segments.Add(new LineSegment(new Point(s, 0), false));

              PathGeometry pg = new PathGeometry();
              pg.Figures.Add(pf);

              fefGlyph.SetValue(Path.DataProperty, pg);
          }
          else
          {
              PathFigure pf = new PathFigure();
              pf.IsClosed = true;
              pf.StartPoint = new Point(0, 0);
              pf.Segments.Add(new LineSegment(new Point(s, s), false));
              pf.Segments.Add(new LineSegment(new Point(s * 2, 0), false));

              PathGeometry pg = new PathGeometry();
              pg.Figures.Add(pf);

              fefGlyph.SetValue(Path.DataProperty, pg);
          }

          FrameworkElementFactory fefTextBlock = 
              new FrameworkElementFactory(typeof(TextBlock));
          fefTextBlock.SetValue(TextBlock.HorizontalAlignmentProperty,
              HorizontalAlignment.Center);
          fefTextBlock.SetValue(TextBlock.TextProperty, new Binding());

          FrameworkElementFactory fefDockPanel = 
              new FrameworkElementFactory(typeof(StackPanel));
          fefDockPanel.SetValue(StackPanel.OrientationProperty,
              Orientation.Vertical);
          fefDockPanel.AppendChild(fefGlyph);
          fefDockPanel.AppendChild(fefTextBlock);

          DataTemplate dt = new DataTemplate(typeof(GridViewColumn));
          dt.VisualTree = fefDockPanel;

          gvc.HeaderTemplate = dt;
      }

      public static DependencyProperty EnableGridViewSortProperty =
          DependencyProperty.RegisterAttached(
              "EnableGridViewSort", 
              typeof(bool), 
              typeof(App), 
              new UIPropertyMetadata(
                  false, 
                  new PropertyChangedCallback(EnableGridViewSortChanged)
              )
          );

      public static bool GetEnableGridViewSort(ListView lv)
      {
          return (bool)lv.GetValue(EnableGridViewSortProperty);
      }

      public static void SetEnableGridViewSort(ListView lv, bool value)
      {
          lv.SetValue(EnableGridViewSortProperty, value);
      }

      public static void EnableGridViewSortChanged(
          object sender, DependencyPropertyChangedEventArgs e)
      {
          ListView lv = sender as ListView;
          if (lv == null) return;

          if (!(e.NewValue is bool)) return;
          bool enableGridViewSort = (bool)e.NewValue;

          if (enableGridViewSort)
          {
              lv.AddHandler(
                  GridViewColumnHeader.ClickEvent,
                  new RoutedEventHandler(EnableGridViewSortGVHClicked)
              );
              if (lv.View == null)
              {
                  lv.Loaded += new RoutedEventHandler(EnableGridViewSortLVLoaded);
              }
              else
              {
                  EnableGridViewSortLVInitialize(lv);
              }
          }
          else
          {
              lv.RemoveHandler(
                  GridViewColumnHeader.ClickEvent,
                  new RoutedEventHandler(EnableGridViewSortGVHClicked)
              );
          }
      }

      public static void EnableGridViewSortLVLoaded(object sender, RoutedEventArgs e)
      {
          ListView lv = e.Source as ListView;
          EnableGridViewSortLVInitialize(lv);
          lv.Loaded -= new RoutedEventHandler(EnableGridViewSortLVLoaded);
      }

      public static void EnableGridViewSortLVInitialize(ListView lv)
      {
          GridView gv = lv.View as GridView;
          if (gv == null) return;

          bool first = true;
          foreach (GridViewColumn gvc in gv.Columns)
          {
              if (first)
              {
                  EnableGridViewSortApplySort(lv, gv, gvc);
                  first = false;
              }
              else
              {
                  CurrentSortColumnSetGlyph(gvc, null);
              }
          }
      }

      public static void EnableGridViewSortGVHClicked(
          object sender, RoutedEventArgs e)
      {
          GridViewColumnHeader gvch = e.OriginalSource as GridViewColumnHeader;
          if (gvch == null) return;
          GridViewColumn gvc = gvch.Column;
          if(gvc == null) return;            
          ListView lv = VisualUpwardSearch<ListView>(gvch);
          if (lv == null) return;
          GridView gv = lv.View as GridView;
          if (gv == null) return;

          EnableGridViewSortApplySort(lv, gv, gvc);
      }

      public static void EnableGridViewSortApplySort(
          ListView lv, GridView gv, GridViewColumn gvc)
      {
          bool isEnabled = GetEnableGridViewSort(lv);
          if (!isEnabled) return;

          string propertyName = GetGridViewSortPropertyName(gvc);
          if (string.IsNullOrEmpty(propertyName))
          {
              Binding b = gvc.DisplayMemberBinding as Binding;
              if (b != null && b.Path != null)
              {
                  propertyName = b.Path.Path;
              }

              if (string.IsNullOrEmpty(propertyName)) return;
          }

          ApplySort(lv.Items, propertyName);
          SetCurrentSortColumn(gv, gvc);
          CurrentSortColumnSetGlyph(gvc, lv);
      }

      public static void ApplySort(ICollectionView view, string propertyName)
      {
          if (string.IsNullOrEmpty(propertyName)) return;

          ListSortDirection lsd = ListSortDirection.Ascending;
          if (view.SortDescriptions.Count > 0)
          {
              SortDescription sd = view.SortDescriptions[0];
              if (sd.PropertyName.Equals(propertyName))
              {
                  if (sd.Direction == ListSortDirection.Ascending)
                  {
                      lsd = ListSortDirection.Descending;
                  }
                  else
                  {
                      lsd = ListSortDirection.Ascending;
                  }
              }
              view.SortDescriptions.Clear();
          }

          view.SortDescriptions.Add(new SortDescription(propertyName, lsd));
      }
      #endregion

      public static T VisualUpwardSearch<T>(DependencyObject source) 
          where T : DependencyObject
      {
          return VisualUpwardSearch(source, x => x is T) as T;
      }

      public static DependencyObject VisualUpwardSearch(
                          DependencyObject source, Predicate<DependencyObject> match)
      {
          DependencyObject returnVal = source;

          while (returnVal != null && !match(returnVal))
          {
              DependencyObject tempReturnVal = null;
              if (returnVal is Visual || returnVal is Visual3D)
              {
                  tempReturnVal = VisualTreeHelper.GetParent(returnVal);
              }
              if (tempReturnVal == null)
              {
                  returnVal = LogicalTreeHelper.GetParent(returnVal);
              }
              else
              {
                  returnVal = tempReturnVal;
              }
          }

          return returnVal;
      }
  }
}

3

আমি মাইক্রোসফ্টের উপায়ে অভিযোজন করেছি, যেখানে আমি এটির জন্য ListViewনিয়ন্ত্রণকে ওভাররাইড করি SortableListView:

public partial class SortableListView : ListView
    {        
        private GridViewColumnHeader lastHeaderClicked = null;
        private ListSortDirection lastDirection = ListSortDirection.Ascending;       

        public void GridViewColumnHeaderClicked(GridViewColumnHeader clickedHeader)
        {
            ListSortDirection direction;

            if (clickedHeader != null)
            {
                if (clickedHeader.Role != GridViewColumnHeaderRole.Padding)
                {
                    if (clickedHeader != lastHeaderClicked)
                    {
                        direction = ListSortDirection.Ascending;
                    }
                    else
                    {
                        if (lastDirection == ListSortDirection.Ascending)
                        {
                            direction = ListSortDirection.Descending;
                        }
                        else
                        {
                            direction = ListSortDirection.Ascending;
                        }
                    }

                    string sortString = ((Binding)clickedHeader.Column.DisplayMemberBinding).Path.Path;

                    Sort(sortString, direction);

                    lastHeaderClicked = clickedHeader;
                    lastDirection = direction;
                }
            }
        }

        private void Sort(string sortBy, ListSortDirection direction)
        {
            ICollectionView dataView = CollectionViewSource.GetDefaultView(this.ItemsSource != null ? this.ItemsSource : this.Items);

            dataView.SortDescriptions.Clear();
            SortDescription sD = new SortDescription(sortBy, direction);
            dataView.SortDescriptions.Add(sD);
            dataView.Refresh();
        }
    }

লাইন ((Binding)clickedHeader.Column.DisplayMemberBinding).Path.Pathবিট সেই কেসগুলি পরিচালনা করে যেখানে আপনার কলামের নামগুলি তাদের বাঁধাই পথগুলির মতো নয়, যা মাইক্রোসফ্ট পদ্ধতি না করে।

আমি GridViewColumnHeader.Clickইভেন্টটি বাধাগ্রস্থ করতে চেয়েছিলাম যাতে আমাকে আর এটি নিয়ে চিন্তা না করতে হবে, তবে করার উপায় আমি খুঁজে পাইনি। ফলস্বরূপ আমি প্রত্যেকের জন্য এক্সএএমএল-তে নিম্নলিখিতগুলি যুক্ত করছি SortableListView:

GridViewColumnHeader.Click="SortableListViewColumnHeaderClicked"

এবং তারপরে Windowযে কোনও সংখ্যক SortableListViewগুলি রয়েছে, কেবল নীচের কোডটি যুক্ত করুন:

private void SortableListViewColumnHeaderClicked(object sender, RoutedEventArgs e)
        {
            ((Controls.SortableListView)sender).GridViewColumnHeaderClicked(e.OriginalSource as GridViewColumnHeader);
        }

আপনি যে Controlsনাম স্থানটিতে SortableListViewনিয়ন্ত্রণ তৈরি করেছেন তার জন্য কেবল এক্সএএমএল আইডি ।

সুতরাং, এটি বাছাই পক্ষের কোড ডুপ্লিকেশন রোধ করে না, আপনি কেবল উপরের মত ইভেন্টটি পরিচালনা করার জন্য মনে রাখতে হবে।


4
আমি আপনার সমাধানটি থেকে অনুপ্রেরণা নিয়েছি এবং গ্রিডভিউ কলমহিডার অ্যাক্সেস করতে একই রাস্তায় নেমে এসেছি event ইভেন্টটি ক্লিক করুন আপনি কনস্ট্রাক্টরে কোনও হ্যান্ডলার যুক্ত করতে পারেন। this.AddHandler (গ্রিডভিউ কলমহিডার.ক্লিকএভেন্ট, নতুন রুটেড এভেন্টহ্যান্ডলার (গ্রিডভিউ কলমহিডার ক্লিক));
ডেরিক মোলার

3

আপনার যদি একটি তালিকা মতামত থাকে এবং এটিকে গ্রিডভিউতে রূপান্তরিত করে আপনি সহজেই আপনার গ্রিডভিউ কলামগুলি শিরোনামকে ক্লিকযোগ্য করে এটি করতে পারেন।

        <Style TargetType="GridViewColumnHeader">
            <Setter Property="Command" Value="{Binding CommandOrderBy}"/>
            <Setter Property="CommandParameter" Value="{Binding RelativeSource={RelativeSource Self},Path=Content}"/>
        </Style>

তারপরে আপনার কোডে একটি প্রতিনিধি কমান্ড সেট করুন।

    public DelegateCommand CommandOrderBy { get { return new DelegateCommand(Delegated_CommandOrderBy); } }

    private void Delegated_CommandOrderBy(object obj)
    {
        throw new NotImplementedException();
    }

আমি ধরে নিচ্ছি আপনারা সবাই এখানে আইকোমন্ড ডেলিগেটকম্যান্ড কীভাবে তৈরি করবেন তা জানেন। এটি আমাকে আমার সমস্ত ভিউ ভিউমোডেলে ক্লিক করে রাখতে দেয়।

আমি কেবল এটি যুক্ত করেছি যাতে একই জিনিসটি সম্পাদনের একাধিক উপায় থাকে। আমি শিরোনামে তীর বোতাম যুক্ত করার জন্য কোড লিখিনি, তবে এটি এক্সএএমএল স্টাইলে করা হবে, জনডটনেটের কোডে আপনাকে পুরো শিরোনামটি পুনরায় ডিজাইন করতে হবে।


0

সমাধান যা কলাম শিরোনাম টেম্পলেটগুলি সহ বিদ্যমান উত্তর এবং মন্তব্যগুলির সমস্ত কার্যকারী অংশের সংক্ষিপ্তসার করে:

দেখুন:

<ListView x:Class="MyNamspace.MyListView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             ItemsSource="{Binding Items}"
             GridViewColumnHeader.Click="ListViewColumnHeaderClick">
    <ListView.Resources>

        <Style TargetType="Grid" x:Key="HeaderGridStyle">
            <Setter Property="Height" Value="20" />
        </Style>

        <Style TargetType="TextBlock" x:Key="HeaderTextBlockStyle">
            <Setter Property="Margin" Value="5,0,0,0" />
            <Setter Property="VerticalAlignment" Value="Center" />
        </Style>

        <Style TargetType="Path" x:Key="HeaderPathStyle">
            <Setter Property="StrokeThickness" Value="1" />
            <Setter Property="Fill" Value="Gray" />
            <Setter Property="Width" Value="20" />
            <Setter Property="HorizontalAlignment" Value="Center" />
            <Setter Property="Margin" Value="5,0,5,0" />
            <Setter Property="SnapsToDevicePixels" Value="True" />
        </Style>

        <DataTemplate x:Key="HeaderTemplateDefault">
            <Grid Style="{StaticResource HeaderGridStyle}">
                <TextBlock Text="{Binding }" Style="{StaticResource HeaderTextBlockStyle}" />
            </Grid>
        </DataTemplate>

        <DataTemplate x:Key="HeaderTemplateArrowUp">
            <Grid Style="{StaticResource HeaderGridStyle}">
                <Path Data="M 7,3 L 13,3 L 10,0 L 7,3" Style="{StaticResource HeaderPathStyle}" />
                <TextBlock Text="{Binding }" Style="{StaticResource HeaderTextBlockStyle}" />
            </Grid>
        </DataTemplate>

        <DataTemplate x:Key="HeaderTemplateArrowDown">
            <Grid Style="{StaticResource HeaderGridStyle}">
                <Path Data="M 7,0 L 10,3 L 13,0 L 7,0"  Style="{StaticResource HeaderPathStyle}" />
                <TextBlock Text="{Binding }" Style="{StaticResource HeaderTextBlockStyle}" />
            </Grid>
        </DataTemplate>

    </ListView.Resources>

    <ListView.View>
        <GridView ColumnHeaderTemplate="{StaticResource HeaderTemplateDefault}">

            <GridViewColumn Header="Name" DisplayMemberBinding="{Binding NameProperty}" />
            <GridViewColumn Header="Type" Width="45" DisplayMemberBinding="{Binding TypeProperty}"/>

            <!-- ... -->

        </GridView>
    </ListView.View>
</ListView>

পিছনে কোড:

public partial class MyListView : ListView
{
    GridViewColumnHeader _lastHeaderClicked = null;

    public MyListView()
    {
        InitializeComponent();
    }

    private void ListViewColumnHeaderClick(object sender, RoutedEventArgs e)
    {
        GridViewColumnHeader headerClicked = e.OriginalSource as GridViewColumnHeader;

        if (headerClicked == null)
            return;

        if (headerClicked.Role == GridViewColumnHeaderRole.Padding)
            return;

        var sortingColumn = (headerClicked.Column.DisplayMemberBinding as Binding)?.Path?.Path;
        if (sortingColumn == null)
            return;

        var direction = ApplySort(Items, sortingColumn);

        if (direction == ListSortDirection.Ascending)
        {
            headerClicked.Column.HeaderTemplate =
                Resources["HeaderTemplateArrowUp"] as DataTemplate;
        }
        else
        {
            headerClicked.Column.HeaderTemplate =
                Resources["HeaderTemplateArrowDown"] as DataTemplate;
        }

        // Remove arrow from previously sorted header
        if (_lastHeaderClicked != null && _lastHeaderClicked != headerClicked)
        {
            _lastHeaderClicked.Column.HeaderTemplate =
                Resources["HeaderTemplateDefault"] as DataTemplate;
        }

        _lastHeaderClicked = headerClicked;
    }


    public static ListSortDirection ApplySort(ICollectionView view, string propertyName)
    {
        ListSortDirection direction = ListSortDirection.Ascending;
        if (view.SortDescriptions.Count > 0)
        {
            SortDescription currentSort = view.SortDescriptions[0];
            if (currentSort.PropertyName == propertyName)
            {
                if (currentSort.Direction == ListSortDirection.Ascending)
                    direction = ListSortDirection.Descending;
                else
                    direction = ListSortDirection.Ascending;
            }
            view.SortDescriptions.Clear();
        }
        if (!string.IsNullOrEmpty(propertyName))
        {
            view.SortDescriptions.Add(new SortDescription(propertyName, direction));
        }
        return direction;
    }
}

4
কোডের কয়েকশ লাইন ফেলে দেওয়া মানে কিছু হচ্ছে না যদি আপনি তাদের কী করছেন তা ব্যাখ্যা না করে
schizoid04

0

কেউ ডাব্লুপিএফ তালিকাভিউকে বাছাই করতে পারে এমন আরও একটি সহজ উপায় যুক্ত করতে চেয়েছিলেন

void SortListView(ListView listView)
{
    IEnumerable listView_items = listView.Items.SourceCollection;
    List<MY_ITEM_CLASS> listView_items_to_list = listView_items.Cast<MY_ITEM_CLASS>().ToList();

    Comparer<MY_ITEM_CLASS> scoreComparer = Comparer<MY_ITEM_CLASS>.Create((first, second) => first.COLUMN_NAME.CompareTo(second.COLUMN_NAME));

    listView_items_to_list.Sort(scoreComparer);
    listView.ItemsSource = null;
    listView.Items.Clear();
    listView.ItemsSource = listView_items_to_list;
}

0

অনুসন্ধান দর্শন পর finaly আমি সহজ এখানে পাওয়া https://www.wpf-tutorial.com/listview-control/listview-how-to-column-sorting/

private GridViewColumnHeader listViewSortCol = null;
private SortAdorner listViewSortAdorner = null;
private void GridViewColumnHeader_Click(object sender, RoutedEventArgs e)
{
  GridViewColumnHeader column = (sender as GridViewColumnHeader);
  string sortBy = column.Tag.ToString();
  if (listViewSortCol != null)
  {
    AdornerLayer.GetAdornerLayer(listViewSortCol).Remove(listViewSortAdorner);
    yourListView.Items.SortDescriptions.Clear();
  }

  ListSortDirection newDir = ListSortDirection.Ascending;
  if (listViewSortCol == column && listViewSortAdorner.Direction == newDir)
    newDir = ListSortDirection.Descending;

  listViewSortCol = column;
  listViewSortAdorner = new SortAdorner(listViewSortCol, newDir);
  AdornerLayer.GetAdornerLayer(listViewSortCol).Add(listViewSortAdorner);
  yourListView.Items.SortDescriptions.Add(new SortDescription(sortBy, newDir));
}

শ্রেণি:

public class SortAdorner : Adorner
{
    private static Geometry ascGeometry =
        Geometry.Parse("M 0 4 L 3.5 0 L 7 4 Z");

    private static Geometry descGeometry =
        Geometry.Parse("M 0 0 L 3.5 4 L 7 0 Z");

    public ListSortDirection Direction { get; private set; }

    public SortAdorner(UIElement element, ListSortDirection dir)
        : base(element)
    {
        this.Direction = dir;
    }

    protected override void OnRender(DrawingContext drawingContext)
    {
        base.OnRender(drawingContext);

        if(AdornedElement.RenderSize.Width < 20)
            return;

        TranslateTransform transform = new TranslateTransform
            (
                AdornedElement.RenderSize.Width - 15,
                (AdornedElement.RenderSize.Height - 5) / 2
            );
        drawingContext.PushTransform(transform);

        Geometry geometry = ascGeometry;
        if(this.Direction == ListSortDirection.Descending)
            geometry = descGeometry;
        drawingContext.DrawGeometry(Brushes.Black, null, geometry);

        drawingContext.Pop();
    }
}

জ্যামল

<GridViewColumn Width="250">
  <GridViewColumn.Header>
    <GridViewColumnHeader Tag="Name" Click="GridViewColumnHeader_Click">Name</GridViewColumnHeader>
  </GridViewColumn.Header>
  <GridViewColumn.CellTemplate>
    <DataTemplate>
        <TextBlock Text="{Binding Name}" ToolTip="{Binding Name}"/>
    </DataTemplate>
  </GridViewColumn.CellTemplate>
</GridViewColumn>

4
ধন্যবাদ অতিরিক্ত পয়েন্টগুলির জন্য, আপনিও ব্যাখ্যা সংক্ষিপ্তসার যুক্ত করতে পারেন? এটি বর্তমানে কেবলমাত্র লিঙ্ক-এবং-কোড (যা ইতিমধ্যে কেবলমাত্র লিঙ্ক-এর চেয়ে ভাল ...)।
Yunnosch

-2

এটা চেষ্টা কর:

using System.ComponentModel;
youtItemsControl.Items.SortDescriptions.Add(new SortDescription("yourFavoritePropertyFromItem",ListSortDirection.Ascending);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.