2009-10-28 9 views
22

Obecnie pracuję w ramach kontroli użytkownika WPF (głównym elementem mojego pliku XAML jest "UserControl"), o którym wiem, że jest hostowana wewnątrz okna. Jak uzyskać dostęp do właściwości okna przy użyciu powiązania danych?Co dokładnie robi "RelativeSource FindAncestor" w WPF Data Binding?

Czy ktoś wie dlaczego po prostu

<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type Window}}" Path="..." /> 

nie działa? Komunikat o błędzie, który otrzymuję, to:

System.Windows.Data Ostrzeżenie: 4: Nie można znaleźć źródła dla wiązania z odniesieniem "RelativeSource FindAncestor, AncestorType =" System.Windows.Window ", AncestorLevel = '1' '.

Edytuj: Skończyło się na wariacji na temat podejścia ArsenMkrt, więc przyjąłem jego odpowiedź. Jednak nadal jestem zainteresowany odkryciem, dlaczego FindAncestor nie działa "po prostu".

+2

Powiedziałeś, że zmieniłeś jego odpowiedź, czy możesz opublikować to, co faktycznie zrobiłeś? – Miles

+0

Zauważ, że szukałem rozwiązania tego problemu w kontekście wzorca MVVM. Własność okna, które chciałem powiązać, była w rzeczywistości własnością Window ViewModel. – user200783

+1

ArsenMkrt zasugerował utworzenie właściwości w UserControl i powiązanie z nią, następnie z kolei (w XAML) powiązanie tej właściwości z pożądaną właściwością Okna. W przypadku wzorca MVVM, UserControl nigdy nie pojawił się w XAML, więc druga część nie była możliwa. – user200783

Odpowiedz

15

Najlepszym sposobem jest nadanie nazwy UserControl

Tworzenie zależności myProperty właściwości w UserControl z dwóch sposób wiązania i wiązania go w oknie głównym niż wiążą się UserControl jak ten

<UserControl x:Name = "myControl"> 
    <Label Content={Binding ElementName= myControl, Path=MyProperty}/> 
</UserControl> 
+0

Ale chcę powiązać właściwość w oknie zawierającym (zdefiniowane w innym pliku XAML), a nie na UserControl. – user200783

+0

Niż będzie lepiej mieć właściwość w usercontrol i powiązać tę właściwość z właściwością okna –

+2

Czy można utworzyć właściwość zależności w UserControl? nie dodajesz usercontrol w oknie?

0

myślę Należy ustawić mode = „OneWayToSource” tak:

<TextBox Text="{Binding RelativeSource={RelativeSource FindAncestor ,AncestorType={x:Type Grid}},Path=BackGround , Mode=OneWayToSource , UpdateSourceTrigger = PropertyChanged}" /> 
4

Jeśli starasz się „ucieczka” z ItemsControl lub DataGridView, aby uzyskać Window możesz stwierdzić, że AncestorType z x:Type Window nie działa. Lub przynajmniej nie wydaje się ...

Jeśli tak jest, to prawdopodobnie działasz w Blend lub Visual Studio i oczekujesz, że dane będą widoczne w czasie projektowania - co nie spowoduje, że VS + Blend zarówno tworzyć własne instancje, które nie są tak naprawdę Windows. Będzie działał w czasie wykonywania, ale nie w trybie projektowania.

Jest kilka rzeczy, które możesz zrobić:

  • Wrap w UserControl

  • Oto alternatywne rozwiązanie mam wymyślić. Ma jedną zaletę polegającą na tym, że nie odwołujesz się bezpośrednio do UserControl lub Window, więc jeśli zmienisz kontener macierzysty, twój kod się nie zepsuje.

    <Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:views="clr-namespace:MyWPFApplication.Views" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     
    x:Class="MyWPFApplication.Views.UPCLabelPrinterWindow" 
    mc:Ignorable="d" 
    x:Name="LayoutRoot" 
    Title="UPCLabelPrinterWindow"> 
    
    <views:DataContextWrapper> 
        <DockPanel> 
         ... 
        </DockPanel> 
    </views:DataContextWrapper> 
    

Gdzie DataContextWrapper tylko Siatka

namespace MyWPFApplication.Views { 
    public class DataContextWrapper : Grid 
    { 

    } 
} 

Wtedy, kiedy wiążą to zrobić:

<TextBlock Text="{Binding="{Binding DataContext.SomeText, 
    RelativeSource={RelativeSource AncestorType={x:Type views:DataContextWrapper}, 
    Mode=FindAncestor}}" /> 

Uwaga: Jeśli chcą wiązać się właściwość samego okna ON jest trudniejsza i powinieneś prawdopodobnie powiązać za pośrednictwem właściwości zależności lub coś podobnego. Ale jeśli używasz MVVM, to jest to jedno z rozwiązań, które znalazłem.

+0

W moim przypadku 'AncestorType = {x: Type Window}' było całkiem pomocne, ponieważ 'AncestorType = UserControl' jakoś nie wskazywało mojego okna - mimo że normalnie to robi. – LuckyLikey

Powiązane problemy