2016-03-23 9 views
0

Ich versuche, einen Parameter meines benutzerdefinierten Steuerelements an eine Liste zu binden. Es sucht jedoch im falschen ViewModel. Es sucht im ViewModel nach meinem Steuerelement (ViewModelUserControlVM) und nicht nach dem ViewModel der Seite, auf der sich mein Steuerelement befindet.Benutzerdefiniertes Steuerelement Bindungsproblem (Windows Universal 10)

Benutzerkontrolle XAML

<UserControl.DataContext> 
    <vm:ViewModelUserControlVM/> 
</UserControl.DataContext> 

<ListView Name="lst"> 
    <ListView.ItemsPanel> 
     <ItemsPanelTemplate> 
      <StackPanel Orientation="Horizontal"/> 
     </ItemsPanelTemplate> 
    </ListView.ItemsPanel> 
</ListView> 

Benutzersteuercode hinter

public object ItemsSource 
    { 
     get 
     { 
      return (object)GetValue(ItemsSourceProperty); 
     } 
     set 
     { 
      SetValue(ItemsSourceProperty, value); 
     } 
    } 

    public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register 
     (
     "ItemsSource", 
     typeof(object), 
     typeof(FlipListview), 
     new PropertyMetadata(
      new object(), 
      new PropertyChangedCallback(OnItemsSourceChanged) 
     ) 
    ); 

Startseite XAML

<local:CustomControl ItemsSource="{Binding list, Mode=TwoWay}"> 

bearbeiten

MainPage.xaml

<Page.DataContext> 
    <vm:MainPageVM/> 
</Page.DataContext> 

MainPageVM

public class MainPageVM : ViewModelBase 
    { 
    public List<Model> list { get; set; } 
    public RelayCommand SelectedItemCommand { get; set; } 

    public Model SelectedItem { get; set; } 

    public MainPageVM() 
    { 
     SelectedItem = new Model(); 
     SelectedItemCommand = new RelayCommand(SelectedItem); 

     list = new List<Model>(); 

     for (int i = 0; i < 5; i++) 
     { 
      list.Add(new Model("url" + i, "title" + i, "desc" + i)); 
     } 
     RaisePropertyChanged(() => list); 
    } 
    } 

Benutzersteuercode hinter

 public CustomControl() 
     { 
     this.InitializeComponent(); 
     } 

Dank im Voraus.

Antwort

0

Wenn die Datacontext Ihrer Usercontrol ist ViewModelUserControlVM, alle Bindungen darin, dass Datacontext aussehen . Wenn Sie ein übergeordnetes Steuerelement zum Binden an die Abhängigkeitseigenschaft benötigen, um etwas von seinem (dem übergeordneten Steuerelement) DataContext zu übergeben, können Sie den DataContext des Hauptsteuerelements von UserControls (Grid, StackPanel usw.) auf ViewModelUserControlVM setzen. Dies bewirkt, dass das Steuerelement selbst in der visuellen Struktur "nach oben" schaut, um einen DataContext zu finden. In diesem Fall das Ansichtsmodell Ihrer MainPage.

Es scheint, dass Sie versuchen, die ItemsSource-Abhängigkeitseigenschaft an etwas in der MainPage zu binden, aber dann den DataContext des UserControls zu überschreiben, indem Sie den DataContext des gesamten Benutzersteuerelements einem anderen Ansichtsmodell zuweisen.

Kompletter Code würde diese Theorie unterstützen oder bestreiten.

Update unter

Vielen Dank für den zusätzlichen Code. Es ist noch unklar, was das ultimative Ziel ist - zum Beispiel wird das ausgewählte Element erwähnt, aber nicht verwendet, und wir kennen die Relevanz des Ansichtsmodells des Benutzersteuerelements nicht. Also habe ich ein kleines Etwas zusammengefügt, das einfach eine Liste im Hauptansichtsmodell anzeigt und an ein Benutzersteuerelement bindet, das nach einer Liste dieses Typs sucht. Ich hoffe, es hilft dir, dorthin zu kommen, wo du versuchst zu gehen ... (Anmerkung: ich die MVVMLight Bibliothek verwendet)

MainPageVM:

public class MainPageVM : ViewModelBase 
    { 
     private List<Model> _list = new List<Model>(); 
     public List<Model> list 
     { 
      get { return _list; } 
      set { Set(ref _list, value); } 
     } 



     public MainPageVM() 
     { 
      for (int i = 0; i < 5; i++) 
      { 
       list.Add(new Model("url" + i, "title" + i, "desc" + i)); 
      } 
      RaisePropertyChanged(() => list); 
     } 
    } 

HauptSeite XAML (Datacontext ist die MainVM):

<Page 
    x:Class="App8.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:App8" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d"> 
    <Page.DataContext> 
     <local:MainPageVM /> 
    </Page.DataContext> 

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 
     <local:CustomControl ItemsSource="{Binding list, Mode=OneWay}" /> 
    </Grid> 
</Page> 

Customcode hinter (beachten Sie die Datacontext-Einstellung im Ctor - Datacontext der Kontrolle ist, was es verwendet, aber die Kontrollen innerhalb des LayoutRoot Raster verwenden die Abhängigkeitseigenschaft Kontrolle):

public CustomControl() 
     { 
      this.InitializeComponent(); 
      LayoutRoot.DataContext = this; 
     } 



     public List<Model> ItemsSource 
     { 
      get { return (List<Model>)GetValue(ItemsSourceProperty); } 
      set { SetValue(ItemsSourceProperty, value); } 
     } 

     // Using a DependencyProperty as the backing store for ItemsSource. This enables animation, styling, binding, etc... 
     public static readonly DependencyProperty ItemsSourceProperty = 
      DependencyProperty.Register("ItemsSource", typeof(List<Model>), typeof(CustomControl), new PropertyMetadata(null, new PropertyChangedCallback(OnItemsSourceChanged))); 

     private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 

     } 
    } 

Custom XAML:

<UserControl 
    x:Class="App8.CustomControl" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:App8" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" 
    d:DesignHeight="300" 
    d:DesignWidth="400"> 

    <Grid x:Name="LayoutRoot"> 
     <ListView Name="lst" ItemsSource="{Binding ItemsSource, Mode=OneWay}" 
        DisplayMemberPath="Url"> 
     </ListView> 
    </Grid> 
</UserControl> 

Auf den Punkt gebracht, die ItemSource des Listview gebunden ist, was auch immer der Customitemssource-Abhängigkeitseigenschaft ist. DataContext von ItemSource von CustomControl ist das, was auch immer DataContext das Steuerelement verwendet. Ich hoffe es hilft dir.

+0

Ich habe meinen Beitrag bearbeitet, um mehr Code einzubinden. – denderp

+0

es ist in der Nähe, aber jetzt funktioniert meine Bindung in meinem CustomControl nicht. Es ist ein Steuerelement in einem Steuerelement in einem Stil, den ich auf Listview anwenden. – denderp

+0

Ich versuche, eine Arbeit zu erledigen. im geladenen Ereignis mache ich das. Stil templatedControl = ((Custom) sender) .lst.Style; SetterBaseCollection set = templatedControl.Setters; Liste list = set.ToList (); Setter Setter = (Setter) Liste [13]; jedoch kann ich nicht die Kontrollen in diesem Setter bekommen. Das ist eine Kontrollschablone. – denderp

0

Vielleicht würde es so funktionieren:

<local:CustomControl ItemsSource="{x:Bind ViewModel.list, Mode=TwoWay}"> 

Sie zusätzliche Informationen über x finden: Bind here

+0

Ich mag nicht mit x: bind, weil es kein Ansichtsmodell verwenden. – denderp

Verwandte Themen