1

XAMLでテンプレートとして定義したいユーザーコントロールがあります。コードビハインドでは、実行時に(ユーザーコントロールタイプの)アイテムをスタックパネルに追加し続けたいと思います。

どうすればいいですか?

私はこれをしたくありません:

myUserControl myUserControl = new MyUserControl;
myStackPanel.Children.Add(myUserControl);

これは、XAMLでUserControlに複数のプロパティを設定しており、コードビハインドからすべてのバインディングを設定したくないためです。よりエレガントなソリューションを探しています。

XAMLでユーザーコントロールのテンプレートを定義するにはどうすればよいですか?次に、このようなことを行うにはどうすればよいですか?

myStackPanel.Children.Add(myCustomControlTemplate);

私はWPFを初めて使用するので、これが非常に些細な質問である場合は、ご容赦ください。

編集:(エルノの要求による)

XAMLファイル

<someNamespace:MyUserControl x:Name="usrControl" SomeState="{Binding CachedValue}" MyUserControlEventAggregator="{Binding ParentEventAggregator}"
                                           DepedencyProperty1="{Binding Property1, Mode=TwoWay}"
                                           DepedencyProperty2="{Binding Property2}"
                                           DepedencyProperty3="{Binding Property3}"
                                           d:DataContext="{Binding Path=ParentViewModel}">

XAML.CSファイル

public partial class ParentControl: Window
{
    public ParentControlViewModel ParentViewModel{ get; set; }

    public ListBuilderView(ParentViewModel viewModelPassedByPRISM)
    {
        ParentViewModel = viewModelPassedByPRISM;
        DataContext = ParentViewModel;
        InitializeComponent();
    }

    private void AddMyUserControlButton_Click(object sender, RoutedEventArgs e)
    {
        // I need to create an instance of MyUserControl here and add it to any WPF component of ParentControl as I may need it for some other user action
    }

    private void ProcessInfoButton_Click(object sender, RoutedEventArgs e)
    {
        // I need to loop through and look into each of the MyUserControls that the user adds, get some values from the MyUserControl and pass this information to do some calc and make some database calls
    }
}

ParentViewModel.csファイル

public class ParentViewModel: BaseViewModel
{
     public IEventAggregator ChildEventAggregator { get; set; }

     private AnyType _property1;
     public AnyType Property1
     {
         get { return _property1; }
         set
         {
             _property1 = value;
             NotifyPropertyChanged("Property1");
         }
     }

     private AnyType _property2;
     public AnyType Property2
     {
         get { return _property2; }
         set
         {
             _property2 = value;
             NotifyPropertyChanged("Property2");
         }
     }

     private AnyType _property3;
     public AnyType Property3
     {
         get { return _property3; }
         set
         {
             _property3 = value;
             NotifyPropertyChanged("Property3");
         }
     }

     public AnyType CachedValue { get; set; }
}

したがって、ご覧のとおり、xaml.csファイルで作成したタイプMyUserControlのすべてのオブジェクトは、共通のプロパティを共有し、自分自身を更新します。ユーザーはこれらのコントロールを操作し、処理を要求するときは、ユーザーがメインコントロールに追加する各MyUserControlを調べ、MyUserControlのメソッドを呼び出して情報を取得し、各MyUserControlからのこれらの情報を他の処理に使用する必要があります。データベースのクエリ。

これがお役に立てば幸いです。

4

1 に答える 1

1

編集

投稿したコードのViewModelプロパティはコレクションであることに注意してください。これらのリストをObservableCollectionに変更することをお勧めします。

これらにバインドするには:USERCONTROLのListBoxなどのitemscontrolを使用します。(ところで:より良いプロパティ名を使用してください!)

これがどのように見えるかです:

<StackPanel>
    <MyUserControl DataContext="{Binding Property1}"/>
    <MyUserControl DataContext="{Binding Property2}"/>
    <MyUserControl DataContext="{Binding Property3}"/>
</StackPanel>

MyUserControlの場合:

<UserControl x:Class="MyUserControl">
    <ListBox ItemsSource="{Binding}">
         <ListBox.ItemTemplate>
             <DataTemplate>
                 <StackPanel Orientation="Horizontal">
                     <TextBlock Text="{Binding AttributeName}"/>
                     <TextBox Text="{Binding AttributeValue}"/>
                 </StackPanel>
             </DataTemplate>
         </ListBox.ItemTemplate>
    </ListBox>
</UserControl>

古い答え-まだ有効 あなたのコメントに応えて:

非常によく似た別のアプローチが必要です。ListBoxなどのItemsControlを使用することで、バインドするコレクションを指定するだけで、コレクション内の各アイテムに対して、ItemTemplateのインスタンス(この場合はユーザーコントロールを含む)が作成され、そのDataContextが設定されます。ユーザーコントロールのバインディングがアイテムに関連するように、アイテムに関連付けます。 

コードにインスタンスを追加したり、各コントロールのDataContextを設定したりする必要はありません。データバインディングの素晴らしい世界へようこそ。

                                                                                                                           

私の推測では、あなたはテンプレートではなくスタイルを探していると思います。

<StackPanel x:Name="MyStackPanel">
    <StackPanel.Resources>
        <Style x:Key="ucStyle" TargetType="MyUserControl">
            <Setter Property="Background" Value="Azure" />
            <Setter Property="BorderThickness" Value="2" />
        </Style>
    </StackPanel.Resources>
</StackPanel>

コード内:

myUserControl myUserControl = new MyUserControl;
Style style = MyStackPanel.FindResource("ucStyle") as Style;
if(style != null)
{
    myUserControl.Style = style;
}
myStackPanel.Children.Add(myUserControl);

または、暗黙のスタイルを使用して、短くなりますが、あまり明白ではありません。

<StackPanel x:Name="MyStackPanel">
    <StackPanel.Resources>
        <Style TargetType="MyUserControl">
            <Setter Property="Background" Value="Azure" />
            <Setter Property="BorderThickness" Value="2" />
        </Style>
    </StackPanel.Resources>
</StackPanel>

コード内:

myUserControl myUserControl = new MyUserControl;
myStackPanel.Children.Add(myUserControl);
于 2012-08-30T05:13:04.020 に答える