2017-06-13 3 views
1

Ich versuche einfach, eine Bindung für ein UserControl in einem UserControl mit WPF/Caliburn zu erstellen, aber ich habe Probleme beim Binden der verschachtelten UserControl. Das grundlegende Layout ist ein ShellViewModel: Conductor, und innerhalb der ShellView gibt es ein ContentControl, das von der ShellViewModel.ActivateItem-Methode gefüllt wird, die ein UserControl (PageViewModel) lädt, und in der PageView UserControl gibt es ein verschachteltes UserControl namens " SimpleControl ".WPF und Caliburn nicht verbindlich verschachtelt UserControl

Die Bindung funktioniert beim Laden der Seite (die Zeichenfolge "Initial Text Value" im verschachtelten UserControl wird angezeigt), scheint jedoch nicht an das PropertyChanged-Ereignis in PageView gebunden zu sein (und aktualisiert den Wert nie beim Test) Taste gedrückt). Das Label im übergeordneten UserControl (PageView) ist korrekt gebunden/wird wie erwartet aktualisiert.

PageView.xaml:

<UserControl x:Class="CaliburnTest.Views.PageView" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:CaliburnTest.Views" 
      xmlns:cal="http://www.caliburnproject.org" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <StackPanel Background="Aqua"> 
     <Label Content="{Binding TextLabelTest, FallbackValue=DEFAULT}"></Label> 
     <local:SimpleControl cal:Bind.Model="WPFCaliburnTemplate.Views.PageView" TextValue="{Binding TextLabelTest}"></local:SimpleControl> 
     <Button Name="UpdateTextButton">Update Text</Button> 
    </StackPanel> 
</UserControl> 

PageViewModel.cs:

using Caliburn.Micro; 

namespace CaliburnTest.ViewModels 
{ 
    public class PageViewModel : Screen 
    { 
     private string _textLabelTest; 
     public string TextLabelTest 
     { 
      get { return _textLabelTest; } 
      set 
      { 
       _textLabelTest = value; 
       NotifyOfPropertyChange(() => TextLabelTest); 
      } 
     } 

     public PageViewModel() 
     { 
      TextLabelTest = "Initial Text Value"; 
     } 

     public void UpdateTextButton() 
     { 
      TextLabelTest = "Updated Text Value"; 
     } 
    } 
} 

SimpleControl.xaml:

<UserControl x:Class="CaliburnTest.Views.SimpleControl" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro.Platform.Core" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <Border Margin="10" BorderThickness="1" BorderBrush="#FF9A9A9A"> 
     <StackPanel> 
      <Label Name="TextLabel"></Label> 
     </StackPanel>   
    </Border> 
</UserControl> 

Und schließlich SimpleControl.xaml.cs:

using System.Windows; 
using System.Windows.Controls; 

namespace CaliburnTest.Views 
{ 
    public partial class SimpleControl : UserControl 
    { 
     public SimpleControl() 
     { 
      InitializeComponent(); 
     } 

     public static DependencyProperty TextValueProperty = DependencyProperty.Register("TextValue", typeof(string), typeof(SimpleControl), 
      new FrameworkPropertyMetadata("", TextValueChangedCallBack)); 
     public string TextValue 
     { 
      get { return (string)GetValue(TextValueProperty); } 
      set 
      { 
       SetValue(TextValueProperty, value); 
       Refresh(); 
      } 
     } 

     protected static void TextValueChangedCallBack(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
     { 
      (sender as SimpleControl).TextValue = (string)e.NewValue; 
     } 

     private void Refresh() 
     { 
      TextLabel.Content = TextValue; 
     } 
    } 
} 

Ich habe den ganzen Tag darauf geklopft und kann nicht herausfinden, was ich falsch mache. Ich habe alle Kombinationen verschiedener DataContexte, RelativeSources und was auch immer ich auf SO und Google finden kann, ausprobiert, komme aber immer noch zu kurz. Ich habe ein viel komplizierteres benutzerdefiniertes Benutzersteuerelement, mit dem ich versuche zu arbeiten, aber ich habe dieses einfache Beispiel erstellt, um das Problem herauszufinden.

Antwort

0

Ich spielte mit allen möglichen Kombinationen und ich glaube, ich ein Ergebnis gefunden, dass, obwohl ich nicht ganz sicher bin, scheint zu funktionieren, warum:

Zuerst habe ich die Art und Weise änderte ich den „Textwert“ wurde die Bindung Abhängigkeitseigenschaft:

<local:SimpleControl TextValue="{Binding RelativeSource={RelativeSource FindAncestor, 
       AncestorType={x:Type UserControl}}, Path=DataContext.TextLabelTest}" /> 

dies wurde jedoch nach wie vor nur für den Anfangswert zu arbeiten und die Bindung wurde nicht aktualisiert, wenn die Zeichenfolge aktualisiert wurde. Am Ende hatte ich SimpleControl.xaml.cs wie so zu bearbeiten:

protected static void TextValueChangedCallBack(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
    { 
     // (sender as SimpleControl).TextValue = (string)e.NewValue; 
     (sender as SimpleControl).Refresh(); 
    } 

Wie Sie sehen können, habe ich aus der Leitung, kommentierte der SimpleControl.TextValue (und wiederum die TextValueProperty DependencyProperty) Einstellung und einfach aufgerufen die SimpleControl.Refresh() -Methode zum Aktualisieren der Beschriftung. Ich bin mir nicht sicher, warum das Setzen der TextValueProperty die DependencyProperty unterbrach (obwohl es bereits festgelegt wurde, als die Zeichenfolge aktualisiert wurde), aber ich denke, ich muss einige MSDN-Artikel auffrischen!