2012-01-10 6 views
0

私はカスタムコントロールを持っていますが、ボタンをクリックすると何度も追加する必要があります。これは、MVVM WPFパターンから得られる必要があります。私はここに自分のコードを貼り付けました。皆さんがこれを手伝うことができれば素晴らしいことでしょう。Viewmodel WPFを使用してスタックパネルにカスタムコントロールを追加

私はそれを次のようにしてください

<Window x:Class="DOCS_APP_ELEMENT.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:usercontrol="clr-namespace:DOCS_APP_ELEMENT" 
    xmlns:viewModel="clr-namespace:DOCS_APP_ELEMENT.ViewModels" 
    Title="MainWindow" Height="350" Width="400"> 
<Grid Margin="10" Name="myGrid"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto"></RowDefinition> 
     <RowDefinition Height="Auto"></RowDefinition> 
     <RowDefinition Height="Auto"></RowDefinition> 
    </Grid.RowDefinitions> 
    <Border CornerRadius="5" BorderBrush="SteelBlue" BorderThickness="2" Grid.Row="0"> 
     <StackPanel Orientation="Vertical"> 
      <StackPanel Orientation="Horizontal"> 
       <Label Content="Type:" Margin="20,0,4,0"></Label> 
       <ComboBox Name="cmbQuestionType" Width="300" Style="{Binding ComboBoxStyle}" Margin="0,5,0,5" IsEnabled="False">     </ComboBox> 
      </StackPanel> 
      <StackPanel Orientation="Horizontal" Margin="0,5,0,5"> 
       <Label Content="Question:" Margin="0,0,4,0"></Label> 
       <TextBox Name="txtQuestion" Width="300" Height="50" Margin="0,2,0,0" AcceptsReturn="True"></TextBox> 
      </StackPanel> 
      <StackPanel Orientation="Horizontal" Margin="0,5,0,5" > 
       <Label Content="Answer:" Margin="7,0,4,0"></Label> 
       <TextBox Name="txtAnswer" Style="{StaticResource TextboxStyle}" Margin="0,2,0,0"></TextBox> 
      </StackPanel> 
     </StackPanel> 
    </Border> 
    <Border CornerRadius="5" BorderBrush="SteelBlue" BorderThickness="2" Grid.Row="1" Margin="0,10,0,0" > 
     <ScrollViewer VerticalScrollBarVisibility="Auto" Height="100"> 
     <StackPanel Name="myCustom" Orientation="Vertical" > 
       **<!--<ADD CUSTOM CONTROl HERE>-->** 
      </StackPanel> 
     </ScrollViewer> 
    </Border> 
    <Border CornerRadius="5" BorderBrush="SteelBlue" BorderThickness="2" Grid.Row="2" Margin="0,10,0,0"> 
     <Border.DataContext> 
      <viewModel:ViewElements/>      
     </Border.DataContext> 
     <Button Name="btnAdd" Content="Add" DataContext="{Binding }" Command="{Binding Path=AddInstace}"></Button> 
    </Border> 
</Grid> 

+0

コントロールを追加するだけですか、コントロールにデータを表示しますか?もしそうなら、ItemsControl en datatemplatesを使うことをお勧めします。 –

+0

新しいカスタムコントロールをここに追加します。カスタムコントロールは複数の他のコントロールになります。 –

+0

私は答えが十分にあなたを助けるつもりだと思う –

答えて

6

私を助けてください:

はあなたのViewModelにObservableCollection<CustomClass>を持っています。 CustomClassの表現は上記のマークアップを持つDataTemplateです。

はここで完全な作業例です:

<Grid> 
    <Grid.DataContext> 
     <local:MyViewModel></local:MyViewModel> 
    </Grid.DataContext> 
     <StackPanel> 
     <ScrollViewer VerticalScrollBarVisibility="Auto" Height="200"> 
     <ItemsControl ItemsSource="{Binding CustomControls}"> 
      <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <Border Background="Green"> 
       <StackPanel> 
        <TextBlock Text="I am a Custom Control"></TextBlock> 
        <TextBlock Text="{Binding DisplayValue}"></TextBlock> 
       </StackPanel> 
       </Border> 
      </DataTemplate> 
      </ItemsControl.ItemTemplate> 
      <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <StackPanel/> 
      </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 
      </ItemsControl> 
     </ScrollViewer> 
     <Button Width="200" Height="50" Command="{Binding AddControlCommand}">Add Control</Button> 
     <Button Width="200" Height="50" Command="{Binding RemoveControlCommand}">Remove Control</Button> 
    </StackPanel> 
    </Grid> 

のViewModel:

public abstract class ViewModel : INotifyPropertyChanged 
    { 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
     PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
    } 

    public class RelayCommand : ICommand 
    { 
    ... look that up yourself if you don't have a derived command class yet in your project... 
    } 

    public class MyViewModel : ViewModel 
    { 
    public ICommand AddControlCommand 
    { 
     get 
     { 
     return new RelayCommand(x=>this.AddControl()); 
     } 
    } 

    public ICommand RemoveControlCommand 
    { 
     get 
     { 
     return new RelayCommand(x => this.RemoveControl()); 
     } 
    } 

    private void AddControl() 
    { 
     CustomControls.Add(new CustomControl() {DisplayValue = "newControl"}); 
    } 

    private void RemoveControl() 
    { 
     if (CustomControls.Count > 0) 
     { 
     CustomControls.Remove(CustomControls.Last()); 
     } 
    } 

    private ObservableCollection<CustomControl> _customControls; 

    public ObservableCollection<CustomControl> CustomControls 
    { 
     get 
     { 
     if (_customControls == null) 
     { 
     _customControls = new ObservableCollection<CustomControl>() 
       { 
        new CustomControl() {DisplayValue = "Control1"}, 
        new CustomControl() {DisplayValue = "Control2"}, 
        new CustomControl() {DisplayValue = "Control3"} 
       }; 
     } 
     return _customControls; 
     } 
    } 
    } 

    public class CustomControl : ViewModel 
    { 
    public string DisplayValue { get; set; } 
    } 
+0

返信いただきありがとうございます。小さなサンプルを作ってください。 –

+0

要求に応じてsamppleが追加されました。 HTH – SvenG

+0

あなたのメールIDを教えてください。だから私は私の問題を解決することができます私のソリューションファイルを送信することができますか? –

4

は、あなたがにバインドされているデータオブジェクトのリストを持っているのViewModelが必要ですMVVMパターンを使用するにはあなたのカスタムコントロール。このコントロールは、ItemsControlによって生成できます。私はあなたのデータを知らないので、私はあなたに一般的な例を与えることができます。

MainWindow.xaml(ビュー)

<ItemsControl ItemsSource="{Binding DataList}"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <!-- instead of the TextBlock you would use your control --> 
      <TextBlock Text="{Binding}" /> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

MainWindow.xaml.cs(ビューコードビハインド)

public MainWindow() 
{ 
    DataContext = new MainWindowViewModel(); 
    InitializeComponent(); 
} 

MainWindowViewModel.cs(ビューモデル)

public class MainWindowViewModel 
{ 
    public ObservableCollection<string> DataList { get; set; } 

    public MainWindowViewModel() 
    { 
     DataList = new ObservableCollection<string> 
        { 
         "Data 1", 
         "Data 2", 
         "Data 3" 
        }; 
    } 
} 

DataContextはDataListの文字列オブジェクトであるため、Textプロパティのバインディングにはパスがありません。複雑なオブジェクトを使用する場合は、オブジェクトのプロパティへのパスを使用する必要があります(Text={Binding Path=myProperty}

+0

ここに私のソリューションファイルを添付する方法。あなたたちはそれを試してみることができます。 –

+0

私はあなたがこれを行うことができるとは思わない。しかし私は、私たちのソリューションがうまくいくと確信しています。それを試してみて、私はあなたがどこかにつかまったことを尋ねます。 – MatthiasG

関連する問題