2010-05-06 14 views
6

के साथ दोवे बाध्यकारी मैं एक उपयोगकर्ता नियंत्रण लिखने की कोशिश कर रहा हूं जिसमें आइटम नियंत्रण है, आइटम टेम्पलेट जिसमें टेक्स्टबॉक्स है जो दोवे बाध्यकारी की अनुमति देगा। हालांकि, मुझे अपने कोड में कहीं गलती करनी होगी, क्योंकि बाध्यकारी केवल काम करता है जैसे मोड = वनवे। यह अपने प्रोजेक्ट से बहुत सरल अंश है, लेकिन यह अभी भी समस्या होती है:आइटम्स कंट्रोल

<UserControl x:Class="ItemsControlTest.UserControl1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Height="300" Width="300"> 
    <Grid> 
     <StackPanel> 
      <ItemsControl ItemsSource="{Binding Path=.}" 
          x:Name="myItemsControl"> 
       <ItemsControl.ItemTemplate> 
        <DataTemplate> 
         <TextBox Text="{Binding Mode=TwoWay, 
               UpdateSourceTrigger=LostFocus, 
               Path=.}" /> 
        </DataTemplate> 
       </ItemsControl.ItemTemplate> 
      </ItemsControl> 
      <Button Click="Button_Click" 
        Content="Click Here To Change Focus From ItemsControl" /> 
     </StackPanel> 
    </Grid> 
</UserControl> 

यहाँ ऊपर नियंत्रण के लिए कोड के पीछे है:

using System; 
using System.Windows; 
using System.Windows.Controls; 
using System.Collections.ObjectModel; 

namespace ItemsControlTest 
{ 
    /// <summary> 
    /// Interaction logic for UserControl1.xaml 
    /// </summary> 
    public partial class UserControl1 : UserControl 
    { 
     public ObservableCollection<string> MyCollection 
     { 
      get { return (ObservableCollection<string>)GetValue(MyCollectionProperty); } 
      set { SetValue(MyCollectionProperty, value); } 
     } 

     // Using a DependencyProperty as the backing store for MyCollection. This enables animation, styling, binding, etc... 
     public static readonly DependencyProperty MyCollectionProperty = 
      DependencyProperty.Register("MyCollection", 
             typeof(ObservableCollection<string>), 
             typeof(UserControl1), 
             new UIPropertyMetadata(new ObservableCollection<string>())); 

     public UserControl1() 
     { 
      for (int i = 0; i < 6; i++) 
       MyCollection.Add("String " + i.ToString()); 

      InitializeComponent(); 

      myItemsControl.DataContext = this.MyCollection; 
     } 

     private void Button_Click(object sender, RoutedEventArgs e) 
     { 
      // Insert a string after the third element of MyCollection 
      MyCollection.Insert(3, "Inserted Item"); 

      // Display contents of MyCollection in a MessageBox 
      string str = ""; 
      foreach (string s in MyCollection) 
       str += s + Environment.NewLine; 
      MessageBox.Show(str); 
     } 
    } 
} 

और अंत में, यहाँ मुख्य विंडो के लिए XAML है :

<Window x:Class="ItemsControlTest.Window1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:src="clr-namespace:ItemsControlTest" 
     Title="Window1" Height="300" Width="300"> 
    <Grid> 
     <src:UserControl1 /> 
    </Grid> 
</Window> 

ठीक है, यह सब कुछ है। मुझे यकीन नहीं है कि टेक्स्टबॉक्स को क्यों संपादित करना है। विंडो में गुण गुण पीछे कोड में बाइंडिंग के लिए स्रोत प्रॉपर्टी को अपडेट नहीं करते हैं, अर्थात् MyCollection। बटन पर क्लिक करने से समस्या मुझे चेहरे पर घूरने का कारण बनती है;) कृपया मुझे यह समझने में मदद करें कि मैं कहां गलत हूं।

Thanx!

एंड्रयू

उत्तर

7

ठीक है मेरा मानना ​​है कि क्या इस समस्या यह है कि आप एक String के लिए सीधे बाध्यकारी हैं है खड़ी कर रहा है। स्ट्रिंग्स सी # में अपरिवर्तनीय और इस प्रकार जब आप टेक्स्ट बदलते हैं, तो यह ObservableCollection में अंतर्निहित स्ट्रिंग को नहीं बदल सकता है। इस समस्या को हल करने के लिए आप क्या कर सकते हैं बस स्ट्रिंग डेटा को पकड़ने के लिए एक मॉडल क्लास बनाते हैं, और उसके बाद TextBox.Text उस कक्षा के अंदर किसी संपत्ति को बांधें।

public partial class BindingToString : Window 
{ 
    public BindingToString() 
    { 
     MyCollection = new ObservableCollection<TestItem>(); 

     for (int i = 0; i < 6; i++) 
      MyCollection.Add(new TestItem("String " + i.ToString())); 

     InitializeComponent(); 

     myItemsControl.DataContext = this.MyCollection; 
    } 

    public ObservableCollection<TestItem> MyCollection 
    { 
     get; 
     set; 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     // Display contents of MyCollection in a MessageBox 
     string str = ""; 
     foreach (TestItem s in MyCollection) 
      str += s.Name + Environment.NewLine; 
     MessageBox.Show(str); 
    } 
} 

public class TestItem 
{ 
    public string Name 
    { 
     get; 
     set; 
    } 

    public TestItem(string name) 
    { 
     Name = name; 
    } 
} 

सूचना है कि मैं एक मानक property- को अपनी निर्भरता संपत्ति बदल वहाँ संग्रह निर्भरता संपत्ति बनाने के लिए कोई कारण नहीं है: यहाँ एक उदाहरण है। इसके अलावा स्ट्रिंग डेटा को पकड़ने के लिए रैपर वर्ग TestItem का एकमात्र अंतर शामिल है।

<Window x:Class="TestWpfApplication.BindingToString" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="BindingToString " Height="300" Width="300"> 
<Grid> 
    <StackPanel> 
     <ItemsControl ItemsSource="{Binding}" 
         x:Name="myItemsControl"> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <TextBox Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 
     <Button Click="Button_Click" 
       Content="Click Here To Change Focus From ItemsControl" /> 
    </StackPanel> 
</Grid> 

अब TextBoxTestItem पर Name पथ के लिए बाध्य है, और यह बाध्यकारी काम करता है और अपेक्षा के अनुरूप संग्रह संशोधित करता है।

+0

यह महान चार्ली है, ऐसा लगता है कि आप इसे नाखुश करते हैं। आप सुझाव अच्छी तरह से काम कर रहे हैं! – Andrew

संबंधित मुद्दे