2017-02-07 13 views
6

मैं एमवीवीएम के लिए बहुत नया हूं और मैं डेटा बाइंडिंग के साथ फंस गया हूं। मेरे पास मेरे व्यू पेज पर एक बटन है जो गतिशील रूप से टेक्स्ट बॉक्स बनाता है लेकिन मैं नहीं देख सकता कि मैं इन टेक्स्टबॉक्स को अपनी सूची में व्यूमोडेल में कैसे बांधता हूं।डायनामिक टेक्स्टबॉक्स किसी सूची में बाध्यकारी

मेरी नजर में मेरे पास है:

<Button x:Name="btWebsite" Grid.ColumnSpan="2" Width="50" Height="50" Click="btWebsite_Click" Margin="23,245,259,202"> 
     <StackPanel x:Name="pnWebsiteButton" Orientation="Horizontal"> 
      <Image x:Name="imgWebsite" Source= "Images/webIcon.jpg" Stretch="Fill" HorizontalAlignment="Left" VerticalAlignment="Top"/> 
     </StackPanel> 
    </Button> 
    <GroupBox x:Name="grpWebsite" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="73,245,0,0" Grid.ColumnSpan="2" Height="51" Width="170" BorderBrush="{x:Null}" BorderThickness="0"> 
     <ScrollViewer x:Name="pnScrollWebsite" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Margin="0,0,0,-6"> 
      <StackPanel x:Name="pnWebsite" Orientation="Vertical" Grid.ColumnSpan="2" HorizontalAlignment="Left" Margin="1,2,0,0" VerticalAlignment="Top" IsEnabled="True"> 

      </StackPanel> 
     </ScrollViewer> 
    </GroupBox> 

बटन के पीछे कोड है:

private void btWebsite_Click(object sender, RoutedEventArgs e) 
{ 
    var newTextBox = new TextBox(); 
    newTextBox.Text = "type the website address..."; 
    newTextBox.Foreground = Brushes.Gray; 
    newTextBox.Width = 150; 
    newTextBox.Name = "txtWebsite" + iWebsites; 
    pnWebsite.Children.Add(newTextBox); 
    pnWebsite.RegisterName(newTextBox.Name, newTextBox); 

    iWebsites++; 
} 

मेरी ViewModel में मेरे पास है:

public List<string> Websites 
{ 
    get { return _websites; } 
    set 
    { 
     if (value != _websites) 
     { 
      _websites = value; 
      OnPropertyChanged("Websites"); 
     } 
    } 
} 

मैं कैसे को देखने के लिए संघर्ष कर रहा हूँ मुझे वेबसाइट टेक्स्टबॉक्स को व्यूमोडेल सूची में मिलता है। आपकी मदद के लिए धन्यवाद

+1

ज्यादा बेहतर उपयोग करने के लिए 'ItemsControl 'वेबसाइट संग्रह के लिए बाध्य:' <आइटम नियंत्रण आइटम स्रोत = "{बाध्यकारी पथ = वेबसाइटें}" /> '। वेबसाइटों को 'अवलोकन करने योग्य चयन ' बनाएं, संग्रह में स्ट्रिंग जोड़ें - और इसे एक दृश्य में प्रदर्शित किया जाएगा – ASh

+0

आप [डब्ल्यूपीएफ चैट रूम] (http://chat.stackoverflow.com/rooms/18165/wpf) से ड्रॉप करना चाहते हैं) .. हम डब्ल्यूपीएफ पर लागू एमवीवीएम पर ध्यान केंद्रित करते हैं। नोट: आपको वहां बात करने के लिए कम से कम 15 प्रतिनिधि की आवश्यकता होगी। –

+0

धन्यवाद लेकिन मेरे पास केवल 11 प्रतिनिधि हैं इसलिए –

उत्तर

1

कोड-पीछे से अपना ईवेंट हैंडलर हटाएं: btWebsite_Click।

इस तरह अपने XAML संशोधित करें:

<Button x:Name="btWebsite" Grid.ColumnSpan="2" Width="50" Height="50" Command="{Binding AddNewStringCommand}" Margin="23,245,259,202"> 
     <StackPanel x:Name="pnWebsiteButton" Orientation="Horizontal"> 
      <Image x:Name="imgWebsite" Source= "Images/webIcon.jpg" Stretch="Fill" HorizontalAlignment="Left" VerticalAlignment="Top"/> 
     </StackPanel> 
</Button> 
<GroupBox x:Name="grpWebsite" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="73,245,0,0" Grid.ColumnSpan="2" Height="51" Width="170" BorderBrush="{x:Null}" BorderThickness="0"> 
    <ScrollViewer x:Name="pnScrollWebsite" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Disabled" Margin="0,0,0,-6"> 
     <StackPanel x:Name="pnWebsite" Orientation="Vertical" Grid.ColumnSpan="2" HorizontalAlignment="Left" Margin="1,2,0,0" VerticalAlignment="Top" IsEnabled="True"> 

      <ItemsControl ItemsSource="{Binding Websites}"> 
       <ItemsControl.ItemTemplate> 
        <DataTemplate> 
         <TextBox Text="{Binding Mode=TwoWay}"/> 
        </DataTemplate> 
       </ItemsControl.ItemTemplate> 
      </ItemsControl> 

     </StackPanel> 
    </ScrollViewer> 
</GroupBox> 

आप भी अपने ViewModel संशोधित करने की आवश्यकता:

public ObservableCollection<string> Websites { get; set; } 

public ICommand AddNewStringCommand => new RelayCommand(AddNewString); 

private void AddNewString() 
{ 
    Websites.Add(string.Empty); 
} 

के बजाय RelayCommand आप ICommand के किसी भी कार्यान्वयन का उपयोग कर सकते हैं। मैं उदाहरण के लिए एमवीवीएमएलइट का उपयोग करता हूं।

जैसा कि आप देख, मुख्य अंतर:

  • इसके बजाय घटना क्लिक से निपटने में, वहाँ एक कमान बटन में बाध्यकारी है।
  • कोड से नए नियंत्रण उत्पन्न करने के बजाय, आइटम नियंत्रण है जो हर बार एक बनाता है जब हमारे पास संग्रह में नया तत्व होता है।
  • नई टेक्स्टबॉक्स की टेक्स्ट प्रॉपर्टी नए तत्व से जुड़ी है।

अद्यतन:

मैं एक गलती की है, ObservableCollection पाठ बॉक्स के साथ सीधे काम नहीं कर रहा।

ऐसा लगता है आप के अलावा कुछ चाहिए:

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

इस तरह ViewModel संशोधित करें:

public ObservableCollection<Website> Websites { get; set; } = new ObservableCollection<Website>(); 

public ICommand AddNewStringCommand => new RelayCommand(AddNewString); 

private void AddNewString() 
{ 
    Websites.Add(new Website {Name = "new website"}); 
} 

और इस तरह ItemsTemplate:

<ItemsControl.ItemTemplate> 
    <DataTemplate> 
     <StackPanel > 
      <TextBox Text="{Binding Name, Mode=TwoWay}"/> 
     </StackPanel> 
    </DataTemplate> 
</ItemsControl.ItemTemplate> 
+0

धन्यवाद, यह अच्छा लग रहा है। मैंने आपके सुझाव को लागू किया है लेकिन अब पेज पर नया टेक्स्ट बॉक्स नहीं दिख रहा है। –

+0

@ थेरेसा फर्ग्यूसन मैंने कुछ अपडेट जोड़ा क्योंकि मैंने परीक्षण किया और यह सही तरीके से काम नहीं कर रहा था। – jannagy02

+0

आपको बहुत बहुत धन्यवाद। यह सब अब काम कर रहा है :-) –

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