السمة IsSynchronizedWithCurrentItem والتحديثات البند الحالية
-
10-07-2019 - |
سؤال
ولدي نموذج بغية إدارة نوع الحوار من الرأي القائل بأن يسمح تصفية من قائمة (إذا لزم الأمر) واختيار عنصر. رمز يعمل بشكل جيد سواء أنا وضعت IsSynchronizedWithCurrentItem إلى true أم لا. ما أفهمه هو أن هذه الخاصية ليست صحيحة افتراضيا في ListView الذي لذلك أود أن فهم هذه الخاصية.
وهنا هو الإعداد ملزمة في XAML وجهة نظر (التي تعمل فقط كذلك دون إعداد خاصية التزامن):
<ListView
ItemsSource="{Binding Projects.View}"
IsSynchronizedWithCurrentItem="True"
SelectedItem="{Binding SelectedProject, Mode=TwoWay}"
>
وومشاريع نموذج عرض هو في الواقع CollectionViewSource التي تدعمها ObservableCollection الخاص. أعتقد أنني glommed هذه الفكرة من مشروع عينة من جوش سميث، لكني بصراحة لا أذكر الآن. هنا هو الجزء ذي الصلة من VM التي تتعلق XAML ملزم:
private ObservableCollection<ProjectViewModel> _projectsInternal { get; set; }
public CollectionViewSource Projects { get; set; }
private void _populateProjectListings(IEnumerable<Project> openProjects) {
var listing = (from p in openProjects
orderby p.Code.ToString()
select new ProjectViewModel(p)).ToList();
foreach (var pvm in listing)
pvm.PropertyChanged += _onProjectViewModelPropertyChanged;
_projectsInternal = new ObservableCollection<ProjectViewModel>(listing);
Projects = new CollectionViewSource {Source = _projectsInternal};
}
/// <summary>Property that is updated via the binding to the view</summary>
public ProjectViewModel SelectedProject { get; set; }
والخاصية تصفية من CollectionViewSource لديها معالج والتي ترجع المسندات المختلفة على عرض العناصر النموذج في القائمة التي التقطت بواسطة الارتباطات بشكل صحيح. هنا هو جوهر هذا الرمز (والذي هو في نفس ProjectSelctionViewModel):
/// <summary>Trigger filtering of the <see cref="Projects"/> listing.</summary>
public void Filter(bool applyFilter)
{
if (applyFilter)
Projects.Filter += _onFilter;
else
Projects.Filter -= _onFilter;
OnPropertyChanged<ProjectSelectionViewModel>(vm=>vm.Status);
}
private void _onFilter(object sender, FilterEventArgs e)
{
var project = e.Item as ProjectViewModel;
if (project == null) return;
if (!project.IsMatch_Description(DescriptionText)) e.Accepted = false;
if (!project.IsMatch_SequenceNumber(SequenceNumberText)) e.Accepted = false;
if (!project.IsMatch_Prefix(PrefixText)) e.Accepted = false;
if (!project.IsMatch_Midfix(MidfixText)) e.Accepted = false;
if (!project.IsAvailable) e.Accepted = false;
}
وضبط الوضع = الاتجاهين لا لزوم لها منذ SelectedItem يكون ListView في الربط اتجاهين افتراضيا، ولكن لا مانع أن تكون صريحة حول هذا الموضوع (I قد تشعر بشكل مختلف عن ذلك مرة واحدة وأنا أفهم WPF أفضل).
وماذا عن قانون بلدي هو جعل IsSynchronizedWithCurrentItem = زائدة عن الحاجة الحقيقية؟
وحدسي هو أن هذا هو كود لائق، ولكن أنا لا أحب أن أجزاء منه ويبدو أن عمل عن طريق "السحر"، وهو ما يعني أنني سوف نرحب بأي اقتراحات بناءة!
وابتهاج،
Berryl
المحلول
وIsSynchronizedWithCurrentItem
المصاحبة لل CurrentItem
لل الافتراضي CollectionView
من جمع المربوطة مع SelectedItem
الخاص بك السيطرة.
ومنذ كنت أبدا استخدام CurrentItem
من CollectionView
والتي لا تظهر على الربط إلى نفس المجموعة مرتين تعيين الخاصية في السؤال ليس له أثر واضح على الإطلاق.
وعرض لكيفية المصاحبة الملكية (للمشاهدين XAML مثل Kaxaml أو XAMLPad):
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<x:Array x:Key="Items" Type="{x:Type sys:String}">
<sys:String>Apple</sys:String>
<sys:String>Orange</sys:String>
<sys:String>Pear</sys:String>
<sys:String>Lime</sys:String>
</x:Array>
</Page.Resources>
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<StackPanel Background="Transparent">
<ListBox IsSynchronizedWithCurrentItem="True" ItemsSource="{StaticResource Items}" />
<ListBox IsSynchronizedWithCurrentItem="True" ItemsSource="{StaticResource Items}" />
<!-- This TextBlock binds to the CurrentItem of the Items via the "/" -->
<TextBlock Text="{Binding Source={StaticResource Items}, Path=/}"/>
</StackPanel>
</ScrollViewer>
</Page>