簡體   English   中英

如何將信息從一個WPF UserControl傳遞到另一個WPF UserControl?

[英]How to pass information from one WPF UserControl to another WPF UserControl?

我有一個WPF應用程序。

在左側有一個堆滿了按鈕的堆疊面板。

在右側有一個空的dockpanel。

當用戶單擊按鈕時 ,它會將相應的UserControl (View) 加載到dockpanel中:

private void btnGeneralClick(object sender, System.Windows.RoutedEventArgs e)
{
    PanelMainContent.Children.Clear();
    Button button = (Button)e.OriginalSource;
    Type type = this.GetType();
    Assembly assembly = type.Assembly;

    IBaseView userControl = UserControls[button.Tag.ToString()] as IBaseView;
    userControl.SetDataContext();

    PanelMainContent.Children.Add(userControl as UserControl);
}

這種模式運行良好,因為每個UserControl都是一個View,它有一個ViewModel類,它從模型中獲取信息,因此用戶可以在頁面之間點擊,每個頁面都可以執行獨立的功能,例如編輯所有客戶,保存到數據庫等

問題:

但是,現在,在其中一個頁面上,我想要一個ListBox,其中包含Customers列表,每個客戶都有一個“編輯”按鈕,當單擊該編輯按鈕時,我想用EditSingleCustomer填充DockPanel UserControl並將其傳遞給需要編輯的客戶。

我可以加載EditCustomer用戶控件,但是如何將客戶編輯並設置其DataContext來編輯該客戶呢?

  • 我無法在構造函數中傳遞它,因為所有UserControl都已創建並存在於MainWindow.xaml.cs中的Dictionary中。
  • 所以我在每個UserControl上創建了一個PrepareUserControl方法並將Customer傳遞給它,並且可以使用x:Name =“...”后面的代碼顯示文本框,但這不是重點,我需要DataBind將ItemsControl轉換為ObservableCollection當然可以利用WPF的數據綁定功能。
  • 所以我試圖將View中的ListBox ItemSource綁定到它后面的代碼,如下所示:

<UserControl.Resources>
    <local:ManageSingleCustomer x:Key="CustomersDataProvider"/>
</UserControl.Resources>

<DockPanel>
    <ListBox ItemsSource="{Binding Path=CurrentCustomersBeingEdited, Source={StaticResource CustomersDataProvider}}"
             ItemTemplate="{DynamicResource allCustomersDataTemplate}"
             Style="{DynamicResource allCustomersListBox}">
    </ListBox>
</DockPanel>

它獲取由該視圖中的IntializeComponent()中的無限循環引起的stackoverflow錯誤。 所以我在想我會以錯誤的方式解決這個問題,必須有一些更簡單的范例來簡單地將命令從一個UserControl傳遞到WPF中的另一個UserControl (在有人說“使用WPF命令”之前,我已經在使用命令了在我的UserControl上,允許用戶編輯所有客戶,這工作正常,但我必須在我的視圖后面的代碼(而不是在我的viewmodel中)處理它,因為我需要父窗口上下文能夠加載另一個用戶控制何時完成保存:

<Button Style="{StaticResource formButton}" 
        Content="Save" 
        Command="local:Commands.SaveCustomer"
        CommandParameter="{Binding}"/>

private void OnSave(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)
{
    Customer customer = e.Parameter as Customer;
    Customer.Save(customer);

    MainWindow parentShell = Window.GetWindow(this) as MainWindow;
    Button btnCustomers = parentShell.FindName("btnCustomers") as Button;
    btnCustomers.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
}

那么在WPF中我怎么能簡單地在DockPanel中加載一個UserControl,在UserControl里面有一個帶有命令的按鈕,它加載另一個UserControl 並向UserControl發送一個可以綁定其控件的特定對象?

我可以想象我此時對WPF命令知之甚少,如果有人能從這里指出正確的方向,那就太好了,或者如果你認為“在DockPanel模式下加載UserControl對於WPF來說是陌生的”應該避免並用另一種方式來構建應用程序“,這也是有用的新聞。 您可以在此處下載我的應用程序的當前狀態,以了解它的結構。 謝謝。

這是您使用Mediator模式的地方。 關於這個主題有幾篇博客文章( 例如 ),並且在一些WPF框架中有模式的實現(例如Prism中的 EventAggregator )。

我剛剛使用WPF完成了一個LOB應用程序,這種問題/模式經常出現,所以這就是我如何解決你的問題:

1)在DataTemplate中,您在ListBox中創建每個項目,以及它的編輯按鈕,將Button的標簽屬性綁定到該列表框項目下面的Customer對象。

2)為按鈕創建Click事件處理程序,並設置Button的Click事件以觸發處理程序。

3)在事件處理程序中,設置UserControl的Content屬性。

4)在用戶控件的范圍內設置DataTemplate(可能在其直接容器的資源中),該描述描述該單個客戶的編輯器。

另一種方法是在EditCustomer類上聲明Customer依賴項屬性,然后在單擊該按鈕時設置該屬性(可能通過XAML Trigger)。

我希望這不是太模糊。 如果不出意外,請知道您遇到的問題在WPF中是可以解決的。

我沒有時間真正深入研究這個問題(這是一個有趣的問題,我希望你得到一個好的答案 - 我可以看到自己未來遇到類似的情況)。

您是否考慮過少一點WPF-y並回退到使用包含客戶的EventArgs在源UserControl上觸發事件,然后在事件處理程序中,在目標控件上觸發相應的命令?

暫無
暫無

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

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