簡體   English   中英

從后面的代碼將控件(在xaml中定義)添加到堆棧面板

[英]Add a control (defined in xaml) to a Stack Panel from Code behind

我有一個要定義為XAML模板的用戶控件。 在后面的代碼中,在運行時,我想繼續將項目(用戶控件類型)添加到堆棧面板。

我該怎么做?

我不想這樣做:

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

這是因為我在XAML中為UserControl設置了多個屬性,並且我不想從后面的代碼中設置所有綁定。 我正在尋找更優雅的解決方案。

如何在XAML中為用戶控件定義模板? 那我該怎么做呢?

myStackPanel.Children.Add(myCustomControlTemplate);

我是WPF的新手,如果這是一個非常瑣碎的問題,請接受我的意見。

編輯:(根據Erno的要求)

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中的這些信息用於其他處理以及查詢數據庫。

我希望這有幫助..

編輯

請注意,您發布的代碼中的ViewModel屬性是集合! 您可能想要將這些列表的更改為ObservableCollection的。

要綁定到這些控件:使用USERCONTROL中的ListBox等項控件。 (順便說一句:請使用更好的屬性名稱!)

看起來像這樣:

<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實例(在這種情況下包含usercontrol),並設置其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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM