मैं listboxes की एक ListBox है कि आपका कोई एप्लिकेशन है। मैं इनरलिस्ट बॉक्स को पारस्परिक रूप से अनन्य बनाना चाहता हूं। मेरे ViewModel एक संग्रह Foos जिसमें कोई वर्णन, एक IsSelected संपत्ति और एक संग्रह बार्स जो एक नाम और IsSelected संपत्ति है है है।WPF परस्पर अनन्य listboxes
public class MyViewModel : INotifyPropertyChanged
{
public ObservableCollection<Foo> Foos { /* code removed for brevity */ }
}
public class Foo : INotifyPropertyChanged
{
public string Description { /* code removed for brevity */ }
public ObservableCollection<Bar> Bars { /* code removed for brevity */ }
public bool IsSelected { /* code removed for brevity */ }
}
public class Bar : INotifyPropertyChanged
{
public string Name { /* code removed for brevity */ }
public bool IsSelected { /* code removed for brevity */ }
}
नीचे मेरी MainWindow जिसका DataContext MyViewModel पर सेट किया जाता का एक हिस्सा है। यह ListBox के ItemsSource संपत्ति ItemsSource={Binding Path=Foos}
का उपयोग कर ही है और इस ListBox के लिए टेम्पलेट में एक आंतरिक ListBox जो ItemsSource="{Binding Path=Bars}"
का उपयोग कर के लिए बाध्य किया जाता है। ए, बी, और सी फूओस विवरण हैं। उनमें शामिल वस्तुओं बार के नाम हैं।
|--------------------------|
| A |--------------------| |
| | Item 1 | |
| | Item 2 | |
| | Item 3 | |
| |--------------------| |
| |
| B |--------------------| |
| | Item X | |
| | Item Y | |
| | Item Z | |
| |--------------------| |
| |
| C |--------------------| |
| | Item l | |
| | Item m | |
| |--------------------| |
|--------------------------|
मुझे इसे बनाने की ज़रूरत है ताकि उपयोगकर्ता किसी भी बार्स में से केवल एक आइटम का चयन कर सके। इसलिए, यदि उपयोगकर्ता Foo A से आइटम 1 का चयन करता है तो Foo B से आइटम एक्स का चयन करता है तो आइटम 1 को अचयनित किया जाना चाहिए।
मैं भी खिड़की पर कहीं और किसी पाठ बॉक्स नियंत्रण के लिए चयनित आइटम के लिए बाध्य करने की जरूरत है, लेकिन 1 बात एक समय मुझे लगता है।
कोड और चयन में इसे बदलना घटनाएं एक विकल्प नहीं है। मैं केवल XAML का उपयोग करके इसे रखना पसंद करूंगा।
अग्रिम धन्यवाद।
अद्यतन
Moonshield की सलाह के बाद मैं इस के साथ आ गया है, लेकिन यह अभी भी पूरी तरह से काम नहीं कर रहा।
public class MyViewModel
{
private Bar _selectedBar;
public ObservableCollection<Foo> Foos { /* code removed for brevity */ }
public Bar SelectedBar
{
get { return _selectedBar; }
set
{
_selectedBar = null;
NotifyPropertyChanged("SelectedBar");
_selectedBar = value;
NotifyPropertyChanged("SelectedBar");
}
}
}
<ListBox x:Name="lbFoos" ItemsSource="{Binding Path=Foos}" SelectedItem="{Binding Path=SelectedBar}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<StackPanel>
<TextBlock Text="Foo: " />
<TextBlock Text="{Binding Path=Description}" />
<ListBox ItemsSource="{Binding Path=Bars}" SelectedItem="{Binding Path=SelectedItem RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ListBox}}}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<TextBlock Text="{Binding Path=Name}" />
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=OneWayToSource}" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
एक चेतावनी जो मैंने चलाया है वह यह है कि यदि सूची बॉक्स की चयनित इटैम संपत्ति किसी संपत्ति से जुड़ी हुई है और संपत्ति उस मूल्य पर ले जाती है जो सूची में नहीं है, तो यह चयनित आइटम को दृष्टिहीन रूप से अचयनित नहीं करेगा। मैंने चयनित ऑब्जेक्ट व्यू मॉडेल प्रॉपर्टी के सेटटर को संशोधित करके इस पर हैकिंग समाप्त कर दी ताकि वह अद्यतनों के बीच 'शून्य' की बदली गई संपत्ति को सूचित करे। यह सही ढंग से सूची बक्से को अचयनित करने का कारण बनता है। –
@Moonshield यह अच्छा लगता है। क्या आप मुझे OneWayToSource बाध्यकारी करने के तरीके के बारे में एक छोटा XAML स्निपेट दे सकते हैं? – Adam
@Dan - उस पर अच्छा पकड़, और एक दिलचस्प समाधान। – Moonshield