نوشته شده توسط
samiasoft
بسیار ممنونم آقای خطی
من حواسم نبوده AlternationCount رو ست نکرده بودم برای همین صفر نشون میداده
تشکر
سلام
البته ، در این روش (در روش پست شماره 9 و 3) ، همونطور که در پست اول تون هم گفته بودین ، این مشکل وجود داره که وقتی اسکرول میشه ، ممکنه ترتیب شون به هم بریزه .
============
دلیل :
این ، بخاطر این هست که Virtualization فعال هست و احتمالا هم نوع مجازی سازی روی حالت Recycle تنظیم شده .
مجازی سازی ، چیزی هست که چون به ازای هر آیتم ، کنترل بصری ایجاد میشه و مخصوصا اگه تعداد آیتم ها هر چی زیادتر باشه ، ساختن کنترل بصری هم اولا بسته به همون تعداد ، زمان خیلی بیشتر و همچنین حجم حافظه ی خیلی زیادی را مصرف میکنه (نسبت به داده ها منظورم هست) ، پس در این حالت ، موقع لود ، مخصوصا هر چی تعداد آیتم ها بیشتر باشه ، زمان لود و مصرف حافظه را هم به همون نسبت طولانی تر میکنه .
برای حل این مشکل ، تکنولوژی مجازی سازی ارائه شد که فقط به همون تعدادِ آیتم هایی که اون کنترلِ ItemsControl (مثل DataGrid) در حال نمایش اش هست و در صفحه نمایش ظاهر میشه (که معمولا تعداد اندک و فرضا 10 یا 20 آیتم را شما در یک لحظه در DataGrid میتونید ببینید) ، به همون تعداد ، کنترل بصری به ازای هر آیتمی که درون کنترلِ ItemsControl میبینید ، کنترلِ بصری در همون لحظه ساخته یا بازیافت میشه .
یعنی هر لحظه ای که اسکرولِ DataGrid را بالا یا پایین میکنید ، در همون لحظه ، اون چند تا کنترل ، ساخته یا بازیافت میشن (ولو اگه تعداد آیتم های DataGrid ، 1 میلیون عدد باشه) .
مجازی سازی ، هم برای سطر و هم برای ستون ، در DataGrid قابل فعال کردن هست که بصورت پیش فرض ، قابلیت مجازی سازی سطرها ، فعال هستند :
DataGrid.EnableRowVirtualization Property (System.Windows.Controls) | Microsoft Learn
احتمالا هم نوع مجازی سازی اش ، از نوع بازیافتی باشه .
حالت بازیافتی ، یعنی وقتی قبلا یه آیتم ای (فرضا سطر ای) را دیده بودید و ساخته بود ، با مراجعه ی مجدد و برگردوندنِ اسکرول به همون آیتم ، دوباره به ازای اون آیتم ، کنترلِ بصریِ جدیدی ساخته نمیشه و از همون شی ای که قبلا براش ساخته شده بود ، استفاده میکنه (که مشکل پست اول تون و همچنین مشکل پست شماره 9 ، بخاطر همین حالت از مجازی سازی هست) .
حالت دیگه ی مجازی سازی ، حالت استاندارد هست که این طور هست که هر وقت ، هر آیتمی در ItemsControl (مثل DataGrid) نمایش داده بشه (توسط بالا یا پایین کردن اسکرول و ...) ، به ازای اون آیتم ها ، کنترلِ بصریِ جدیدی ساخته میشه . چه قبلا دیده بودید و کنترلی وجود داشت یا نه :
VirtualizationMode Enum (System.Windows.Controls) | Microsoft Learn
==========
راهکار :
برای اینکه همون مشکلی که در پست 9 و 3 هست رفع بشه ، باید حالتِ مجازی سازی را در DataGrid ، روی حالتِ استاندارد (Standard) بذارید :
wpf - DataGrid row virtualization display issue - Stack Overflow
برای این کار ، طبق لینک بالا (و همچنین لینک قبلی تر) ، در DataGrid (یا هر ItemsControl ای که مورد نظرتون هست) ، دو پروپرتیِ زیر را قرار بدید :
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Standar d"
یعنی مثلا این طوری :
<DataGrid Name="PhoneBookDataGrid" HorizontalAlignment="Center" Height="240"
Margin="0,153,0,0" VerticalAlignment="Top" Width="780"
AutoGenerateColumns="False"
ItemsSource="{Binding ValidatesOnExceptions=True}"
AlternationCount="{Binding Count}"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Standar d">
<DataGrid.Columns>
<DataGridTextColumn Header="ردیف" IsReadOnly="True"
Binding="{Binding AlternationIndex,
RelativeSource={RelativeSource AncestorType=DataGridRow}}"/>
</DataGrid.Columns>
</DataGrid>
دقت کنید که اون دو خط کد را اگه در DataGrid با دست بخواین بنویسین ، توی لیست اینتلایسنس ، نمیاره .
فرضا اگه عبارتِ VirtualizingStackPanel را بنویسید ، و نقطه بذارید ، عضوِ IsVirtualizing اش را نمیاره .
بلکه باید خودتون این خط ها را در DataGrid (و ...) ، کپی و paste کنین .
همچنین دقت کنید که در کد بالا ، در عبارت Standard ، بین حرف r و حرف d ، فاصله افتاد که این فاصله وجود نداره (نمیدونم چرا در این انجمن فاصله میافته) .
راهکار دیگه اینه که کلا مجازی سازی سطرها را غیرفعال کنید که پیشنهاد نمیشه .