मेरे पास एक कॉम्बोबॉक्स है जो चयनित इटैम/चयनित वैल्यू को अपडेट नहीं करता है।एक कस्टम सूची में बाध्यकारी WPF कॉम्बोबॉक्स
ComboBox ItemsSource SelectedItem
या SelectedValue
ViewModel का एक और संपत्ति के लिए (अलग समय पर) एक ViewModel वर्ग है कि एक CollectionView के रूप में रास फोनबुक प्रविष्टियों का एक समूह को सूचीबद्ध करता है पर एक संपत्ति के लिए बाध्य है, तो मैं बाध्य किया है दोनों। मैंने डाटाबेस द्वारा सेट किए गए मान डीबग करने के लिए सेव कमांड में एक संदेशबॉक्स जोड़ा है, लेकिन SelectedItem
/SelectedValue
बाध्यकारी सेट नहीं किया जा रहा है।
public ConnectionViewModel
{
private readonly CollectionView _phonebookEntries;
private string _phonebookeEntry;
public CollectionView PhonebookEntries
{
get { return _phonebookEntries; }
}
public string PhonebookEntry
{
get { return _phonebookEntry; }
set
{
if (_phonebookEntry == value) return;
_phonebookEntry = value;
OnPropertyChanged("PhonebookEntry");
}
}
}
_phonebookEntries संग्रह एक व्यापार वस्तु से निर्माता में initialised किया जा रहा है:
ViewModel वर्ग इस तरह दिखता है। ComboBox XAML इस तरह दिखता है:
<ComboBox ItemsSource="{Binding Path=PhonebookEntries}"
DisplayMemberPath="Name"
SelectedValuePath="Name"
SelectedValue="{Binding Path=PhonebookEntry}" />
मैं केवल ComboBox में दिखाया गया है वास्तविक स्ट्रिंग मान में दिलचस्पी है, न इस के रूप में वस्तु के किसी भी अन्य गुण मूल्य मैं जब मैं रास करने के लिए भर में पारित करने के लिए की जरूरत है वीपीएन कनेक्शन बनाना चाहते हैं, इसलिए DisplayMemberPath
और SelectedValuePath
दोनों ConnectionViewModel की नाम संपत्ति दोनों हैं। कॉम्बोबॉक्स DataTemplate
में एक विंडो पर ItemsControl
पर लागू है जिस पर डेटाकॉन्टेक्स्ट को व्यूमोडेल इंस्टेंस पर सेट किया गया है।
कॉम्बोबॉक्स सही वस्तुओं की सूची प्रदर्शित करता है, और मैं बिना किसी समस्या के यूआई में एक का चयन कर सकता हूं। हालांकि जब मैं कमांड से संदेश बॉक्स प्रदर्शित करता हूं, तो फोनबुक एंटर्री प्रॉपर्टी में अभी भी प्रारंभिक मान है, कॉम्बोबॉक्स से चयनित मूल्य नहीं। अन्य टेक्स्टबॉक्स उदाहरण संदेश अपडेट में ठीक और प्रदर्शित कर रहे हैं।
मुझे कॉम्बोबॉक्स डेटाबेस के साथ क्या याद आ रही है? मैंने बहुत सी खोज की है और ऐसा कुछ भी नहीं लगता है जो मैं गलत कर रहा हूं।
यह वह व्यवहार है जिसे मैं देख रहा हूं, हालांकि यह मेरे विशेष संदर्भ में किसी कारण से काम नहीं कर रहा है।
मेरे पास एक MainWindowViewModel है जिसमें कनेक्शन ViewModels का CollectionView
है। MainWindowView.xaml फ़ाइल कोड-बैक में, मैंने DataContext को MainWindowViewModel पर सेट किया है। MainWindowView.xaml में ItemsControl
कनेक्शन कनेक्शन दृश्य संग्रह के लिए बाध्य है। मेरे पास एक डेटा टेम्पलेट है जिसमें कॉम्बोबॉक्स और साथ ही कुछ अन्य टेक्स्टबॉक्स भी हैं। टेक्स्टबॉक्स सीधे Text="{Binding Path=ConnectionName}"
का उपयोग कर कनेक्शन व्यू मॉडेल के गुणों से बंधे हैं।
public class ConnectionViewModel : ViewModelBase
{
public string Name { get; set; }
public string Password { get; set; }
}
public class MainWindowViewModel : ViewModelBase
{
// List<ConnectionViewModel>...
public CollectionView Connections { get; set; }
}
XAML कोड-पीछे:
public partial class Window1
{
public Window1()
{
InitializeComponent();
DataContext = new MainWindowViewModel();
}
}
फिर XAML:
<DataTemplate x:Key="listTemplate">
<Grid>
<ComboBox ItemsSource="{Binding Path=PhonebookEntries}"
DisplayMemberPath="Name"
SelectedValuePath="Name"
SelectedValue="{Binding Path=PhonebookEntry}" />
<TextBox Text="{Binding Path=Password}" />
</Grid>
</DataTemplate>
<ItemsControl ItemsSource="{Binding Path=Connections}"
ItemTemplate="{StaticResource listTemplate}" />
बक्सें सही ढंग से सब बाँध, और उन्हें और कोई परेशानी नहीं के साथ ViewModel के बीच डेटा ले जाता है। यह केवल कॉम्बोबॉक्स है जो काम नहीं कर रहा है।
आप फोनबुक एंटर्री क्लास के बारे में अपनी धारणा में सही हैं।
मैं जो धारणा बना रहा हूं वह यह है कि मेरे डेटा टेम्पलेट द्वारा उपयोग किया गया डेटाकॉन्टेक्स्ट स्वचालित रूप से बाइंडिंग पदानुक्रम के माध्यम से सेट किया जाता है, ताकि मुझे इसे ItemsControl
में प्रत्येक आइटम के लिए स्पष्ट रूप से सेट करने की आवश्यकता न हो। यह मेरे लिए थोड़ा मूर्खतापूर्ण प्रतीत होता है।
यहां एक परीक्षण कार्यान्वयन है जो ऊपर दिए गए उदाहरण के आधार पर समस्या का प्रदर्शन करता है।
XAML:
<Window x:Class="WpfApplication7.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<DataTemplate x:Key="itemTemplate">
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Path=Name}" Width="50" />
<ComboBox ItemsSource="{Binding Path=PhonebookEntries}"
DisplayMemberPath="Name"
SelectedValuePath="Name"
SelectedValue="{Binding Path=PhonebookEntry}"
Width="200"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<ItemsControl ItemsSource="{Binding Path=Connections}"
ItemTemplate="{StaticResource itemTemplate}" />
</Grid>
</Window>
कोड-पीछे:
namespace WpfApplication7
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
DataContext = new MainWindowViewModel();
}
}
public class PhoneBookEntry
{
public string Name { get; set; }
public PhoneBookEntry(string name)
{
Name = name;
}
}
public class ConnectionViewModel : INotifyPropertyChanged
{
private string _name;
public ConnectionViewModel(string name)
{
_name = name;
IList<PhoneBookEntry> list = new List<PhoneBookEntry>
{
new PhoneBookEntry("test"),
new PhoneBookEntry("test2")
};
_phonebookEntries = new CollectionView(list);
}
private readonly CollectionView _phonebookEntries;
private string _phonebookEntry;
public CollectionView PhonebookEntries
{
get { return _phonebookEntries; }
}
public string PhonebookEntry
{
get { return _phonebookEntry; }
set
{
if (_phonebookEntry == value) return;
_phonebookEntry = value;
OnPropertyChanged("PhonebookEntry");
}
}
public string Name
{
get { return _name; }
set
{
if (_name == value) return;
_name = value;
OnPropertyChanged("Name");
}
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class MainWindowViewModel
{
private readonly CollectionView _connections;
public MainWindowViewModel()
{
IList<ConnectionViewModel> connections = new List<ConnectionViewModel>
{
new ConnectionViewModel("First"),
new ConnectionViewModel("Second"),
new ConnectionViewModel("Third")
};
_connections = new CollectionView(connections);
}
public CollectionView Connections
{
get { return _connections; }
}
}
}
आपको लगता है कि उदाहरण चलाते हैं, तो आप व्यवहार के बारे में मैं बात कर रहा हूँ मिल जाएगा। जब आप इसे संपादित करते हैं तो टेक्स्टबॉक्स अपने बाध्यकारी जुर्माना को अद्यतन करता है, लेकिन कॉम्बोबॉक्स नहीं करता है। वास्तव में एकमात्र चीज जो मैंने किया है, बहुत ही भ्रमित करने वाला एक माता-पिता ViewModel पेश करता है।
मैं वर्तमान में इस धारणा के तहत श्रम कर रहा हूं कि डेटाकॉन्टेक्स्ट के बच्चे से जुड़ी एक वस्तु में उस बच्चे को डेटाकॉन्टेक्स्ट है। मुझे कोई दस्तावेज नहीं मिल रहा है जो इसे एक तरफ या दूसरे को साफ़ करता है।
Ie,
खिड़की -> DataContext = MainWindowViewModel
..Items -> DataContext.PhonebookEntries
को बाउंड .... मद -> DataContext = PhonebookEntry (परोक्ष जुड़े)
मैं डॉन यह नहीं पता कि क्या मेरी धारणा किसी भी बेहतर तरीके से बताती है?
मेरी धारणा की पुष्टि करने के लिए,
<TextBox Text="{Binding Mode=OneWay}" Width="50" />
होने के लिए पाठ बॉक्स के बंधन को बदलने और इस टेक्स्ट बॉक्स बाध्यकारी रूट (जो मैं DataContext की तुलना कर रहा हूँ) ConnectionViewModel उदाहरण है दिखाएगा।
मैं पुष्टि कर सकता हूं कि संग्रह को बदलना, जिस पर 'आइटम स्रोत' संपत्ति बाध्य है, केवल पढ़ने के लिए संग्रह ही इसे काम करता है। मेरे मामले में मुझे इसे 'ऑब्जर्जेबल कोलेक्शन' से 'ReadOnlyObservableCollection' में बदलना पड़ा। नट। यह .NET 3.5 है - यह सुनिश्चित नहीं है कि यह 4.0 – ChrisWue
में तय किया गया है, मैंने उस संदेश को भी नोटिस किया था, लेकिन मुझे लगता है कि * कवर किया गया था * मूल डेटा बाध्यकारी होगा। मुझे नहीं लगता। :) अब मैं गुणों को उजागर कर रहा हूं जैसे कि IList' <'T'> 'और आपके द्वारा उल्लिखित तरीके से _list.AsReadOnly() का उपयोग करके संपत्ति गेटर में। यह काम कर रहा है क्योंकि मैं उम्मीद करता था कि मूल विधि होगी। साथ ही, यह मेरे दिमाग को पार कर गया कि जब आइटमसोर्स बाध्यकारी ठीक काम कर रहा था, तो मैं कॉम्बोबॉक्स में चयनित आइटम तक पहुंचने के लिए व्यूमोडेल में वर्तमान प्रॉपर्टी का उपयोग कर सकता था। फिर भी, यह कॉम्बोबॉक्स चयनितवैल/चयनित इटैम संपत्ति को बाध्यकारी के रूप में प्राकृतिक महसूस नहीं करता है। –