Jak używać wiązań WPF z RelativeSource?

Jak używać RelativeSource z wiązaniami WPF i jakie są różne przypadki użycia?

Author: shekhar, 2008-09-17

14 answers

Jeśli chcesz powiązać z inną właściwością obiektu:

{Binding Path=PathToProperty, RelativeSource={RelativeSource Self}}

Jeśli chcesz uzyskać własność na przodku:

{Binding Path=PathToProperty,
    RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}

Jeśli chcesz uzyskać Właściwość na rodzicu szablonów (dzięki czemu możesz zrobić 2 wiązania w ControlTemplate)

{Binding Path=PathToProperty, RelativeSource={RelativeSource TemplatedParent}}

Lub, krótszy (działa to tylko dla wiązań OneWay):

{TemplateBinding Path=PathToProperty}
 704
Author: Abe Heidebrecht,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-31 09:26:46
Binding RelativeSource={
    RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemType}
}
...

Domyślnym atrybutem {[1] } jest właściwość Mode. Tutaj podano kompletny zestaw ważnych wartości ( z MSDN):

  • PreviousData umożliwia powiązanie poprzedniej pozycji danych (nie kontrolki, która zawiera pozycję danych) z listą wyświetlanych pozycji danych.

  • TemplatedParent odnosi się do elementu, do którego został zastosowany szablon (w którym istnieje element związany z danymi). Jest to podobne do Ustawienia TemplateBindingExtension i ma zastosowanie tylko wtedy, gdy powiązanie znajduje się w szablonie.

  • Self odnosi się do elementu, na którym ustawiasz wiązanie i pozwala powiązać jedną właściwość tego elementu z inną właściwością tego samego elementu.

  • FindAncestor odnosi się do przodka w łańcuchu nadrzędnym elementu związanego z danymi. Można tego użyć do powiązania z przodkiem określonego typu lub jego podklasami. Jest to tryb, którego używasz, jeśli chcesz określić AncestorType i / lub AncestorLevel.

 123
Author: Drew Noakes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-03 09:24:23

Oto bardziej wizualne wyjaśnienie w kontekście architektury MVVM:

Tutaj wpisz opis obrazka

 114
Author: Jeff K.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-05 21:43:26

Wyobraźmy sobie ten przypadek, prostokąt, który chcemy, aby jego wysokość była zawsze równa jego szerokości, powiedzmy kwadrat. Możemy to zrobić używając nazwy elementu

<Rectangle Fill="Red" Name="rectangle" 
                    Height="100" Stroke="Black" 
                    Canvas.Top="100" Canvas.Left="100"
                    Width="{Binding ElementName=rectangle,
                    Path=Height}"/>

Ale w powyższym przypadku jesteśmy zobowiązani do podania nazwy obiektu wiążącego, czyli prostokąta. Możemy osiągnąć ten sam cel w różny sposób używając RelativeSource

<Rectangle Fill="Red" Height="100" 
                   Stroke="Black" 
                   Width="{Binding RelativeSource={RelativeSource Self},
                   Path=Height}"/>

W tym przypadku nie jesteśmy zobowiązani do podania nazwy obiektu wiążącego, a szerokość będzie zawsze równa wysokości, gdy tylko zmiana wysokości.

Jeśli chcesz parametrować Szerokość jako połowę wysokości, możesz to zrobić, dodając konwerter do rozszerzenia znaczników wiązania. Wyobraźmy sobie teraz inny przypadek:

 <TextBlock Width="{Binding RelativeSource={RelativeSource Self},
                   Path=Parent.ActualWidth}"/>

Powyższy przypadek jest używany do powiązania danej właściwości danego elementu z jedną z jego bezpośrednich rodzicielskich, ponieważ element ten posiada właściwość, która jest nazywana rodzicem. To prowadzi nas do innego względnego trybu źródła, który jest FindAncestor jeden.

 40
Author: lasitha edirisooriya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-09 05:47:07

Bechir Bejaoui ujawnia przypadki użycia RelativeSources w WPF w jego artykuł tutaj :

RelativeSource jest rozszerzeniem znaczników, które jest używane w szczególności wiążące przypadki, gdy staramy się powiązać właściwość danego obiektu z inną właściwością samego obiektu, gdy staramy się powiązać właściwość przedmiotu do innego z jego krewnych rodziców, gdy wiążąc właściwość zależności value to a piece of XAML in case of custom control rozwój i wreszcie w przypadku zastosowania różniczkowania szeregów związane dane. Wszystkie te sytuacje są wyrażone jako względne źródło tryby. Ujawnię wszystkie te sprawy jeden po drugim.

  1. Mode Self:

Wyobraźmy sobie ten przypadek, prostokąt, który chcemy, aby jego wysokość była zawsze równa jego szerokości, powiedzmy kwadrat. Możemy to zrobić za pomocą Nazwa elementu

<Rectangle Fill="Red" Name="rectangle" 
                Height="100" Stroke="Black" 
                Canvas.Top="100" Canvas.Left="100"
                Width="{Binding ElementName=rectangle,
                Path=Height}"/>

Ale w powyższym przypadku jesteśmy zobowiązani do podania nazwy obiekt wiążący, mianowicie prostokąt. Możemy osiągnąć ten sam cel inaczej używając RelativeSource

<Rectangle Fill="Red" Height="100" 
               Stroke="Black" 
               Width="{Binding RelativeSource={RelativeSource Self},
               Path=Height}"/>

W tym przypadku nie jesteśmy zobowiązani do podania nazwy wiążącej obiekt i szerokość będzie zawsze równa wysokości za każdym razem, gdy zmiana wysokości.

Jeśli chcesz określić szerokość jako połowę wysokości, to można to zrobić, dodając konwerter do rozszerzenia znaczników wiążących. Wyobraźmy sobie teraz inny przypadek:

 <TextBlock Width="{Binding RelativeSource={RelativeSource Self},
               Path=Parent.ActualWidth}"/>

Powyżej case służy do powiązania danej własności danego elementu z jednym z jego bezpośrednich rodziców, ponieważ element ten posiada właściwość, która jest zwany rodzicem. To prowadzi nas do innego względnego trybu źródła, który jest FindAncestor 1.

  1. Mode FindAncestor

W tym przypadku właściwość danego elementu będzie powiązana z jednym z jego rodzice z Corse. Główną różnicą w stosunku do powyższego przypadku jest fakt to do ciebie należy określenie typu przodka i przodek pozycję w hierarchii, aby powiązać własność. Przy okazji spróbuj grać z ten kawałek XAML

<Canvas Name="Parent0">
    <Border Name="Parent1"
             Width="{Binding RelativeSource={RelativeSource Self},
             Path=Parent.ActualWidth}"
             Height="{Binding RelativeSource={RelativeSource Self},
             Path=Parent.ActualHeight}">
        <Canvas Name="Parent2">
            <Border Name="Parent3"
            Width="{Binding RelativeSource={RelativeSource Self},
           Path=Parent.ActualWidth}"
           Height="{Binding RelativeSource={RelativeSource Self},
              Path=Parent.ActualHeight}">
               <Canvas Name="Parent4">
               <TextBlock FontSize="16" 
               Margin="5" Text="Display the name of the ancestor"/>
               <TextBlock FontSize="16" 
                 Margin="50" 
            Text="{Binding RelativeSource={RelativeSource  
                       FindAncestor,
                       AncestorType={x:Type Border}, 
                       AncestorLevel=2},Path=Name}" 
                       Width="200"/>
                </Canvas>
            </Border>
        </Canvas>
     </Border>
   </Canvas>

Powyższa sytuacja dotyczy dwóch elementów TextBlock, które są osadzone w ramach szeregu obramowań i elementów płótna, które reprezentują ich hierarchiczni rodzice. Drugi blok tekstowy wyświetli nazwę danego rodzica na względnym poziomie źródła.

Więc spróbuj zmienić AncestorLevel=2 Na AncestorLevel=1 i zobacz co zdarza się. Następnie spróbuj zmienić rodzaj przodka z AncestorType = Border to AncestorType=Canvas i zobacz co się dzieje.

Wyświetlany tekst zmieni się w zależności od typu przodka i poziom. Wtedy co się stanie, jeśli poziom przodka nie jest odpowiedni do Typ przodka? To jest dobre pytanie, wiem, że masz zamiar zapytaj. Odpowiedź jest nie wyjątki zostaną rzucone i nic nie będzie być wyświetlane na poziomie bloku tekstowego.

  1. TemplatedParent

To tryb umożliwia powiązanie danej właściwości ControlTemplate z właściwością kontrolki, do której stosuje się ControlTemplate. Do studni zrozumieć problem tutaj jest przykład poniżej

<Window.Resources>
<ControlTemplate x:Key="template">
        <Canvas>
            <Canvas.RenderTransform>
                <RotateTransform Angle="20"/>
                </Canvas.RenderTransform>
            <Ellipse Height="100" Width="150" 
                 Fill="{Binding 
            RelativeSource={RelativeSource TemplatedParent},
            Path=Background}">

              </Ellipse>
            <ContentPresenter Margin="35" 
                  Content="{Binding RelativeSource={RelativeSource  
                  TemplatedParent},Path=Content}"/>
        </Canvas>
    </ControlTemplate>
</Window.Resources>
    <Canvas Name="Parent0">
    <Button   Margin="50" 
              Template="{StaticResource template}" Height="0" 
              Canvas.Left="0" Canvas.Top="0" Width="0">
        <TextBlock FontSize="22">Click me</TextBlock>
    </Button>
 </Canvas>

Jeśli chcę zastosować właściwości danej kontrolki do jej kontrolki szablon następnie mogę użyć trybu TemplatedParent. Istnieje również podobne do tego rozszerzenia znaczników, którym jest TemplateBinding co jest rodzajem krótkiej ręki pierwszej, ale TemplateBinding jest oceniany na czas kompilacji przy kontraście TemplatedParent, który jest oceniany zaraz po pierwszym uruchomieniu. Jako możesz zauważyć w poniższym rysunku, tle i treści są stosowane z poziomu przycisku do szablonu sterującego.

 34
Author: Cornel Marian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-02 16:51:29

Nie zapomnij o TemplatedParent:

<Binding RelativeSource="{RelativeSource TemplatedParent}"/>

Lub

{Binding RelativeSource={RelativeSource TemplatedParent}}
 18
Author: Bob King,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-17 15:14:34

w WPF RelativeSource Wiązanie wyświetla trzy {[6] } do Ustawienia:

1. Mode: To jest enum, który może mieć cztery wartości:

A. PreviousData(value=0): przypisuje poprzednią wartość property do the bound one

b. szablon(value=1): jest to używane przy definiowaniu templates z Dowolna kontrola i chcesz powiązać z wartością / właściwością control.

Na przykład, define ControlTemplate:

  <ControlTemplate>
        <CheckBox IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
 </ControlTemplate>

C. Self(value=2): kiedy chcemy związać się z self lub property jaźni.

Na przykład: Wyślij sprawdzony stan checkbox jako CommandParameter podczas ustawiania Command na CheckBox

<CheckBox ...... CommandParameter="{Binding RelativeSource={RelativeSource Self},Path=IsChecked}" />

D. FindAncestor(value=3): gdy chcesz związać z rodzicem control w Visual Tree.

Na przykład: Bind a checkbox in records if a grid, if header checkbox jest sprawdzane

<CheckBox IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid}}, Path=DataContext.IsHeaderChecked, Mode=TwoWay}" />

2. AncestorType: gdy mode to FindAncestor to określ jaki typ przodka

RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid}}

3. AncestorLevel: gdy mode jest FindAncestor, to na jakim poziomie przodka (jeśli w visual tree są dwa tego samego typu rodzice)

RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid, AncestorLevel=1}}

Powyżej są wszystkie przypadki użycia dla RelativeSource binding.

Oto odnośnik .

 16
Author: Kylo Ren,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-19 09:24:28

Warto zauważyć, że dla tych, którzy natknęli się na to myślenie o Silverlight:

Silverlight oferuje tylko zredukowany podzbiór, z tych poleceń

 13
Author: Matthew Black,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-24 16:02:46

Stworzyłem bibliotekę, aby uprościć składnię wiążącą WPF, w tym ułatwić korzystanie z RelativeSource. Oto kilka przykładów. Przed:

{Binding Path=PathToProperty, RelativeSource={RelativeSource Self}}
{Binding Path=PathToProperty, RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}
{Binding Path=PathToProperty, RelativeSource={RelativeSource TemplatedParent}}
{Binding Path=Text, ElementName=MyTextBox}

Po:

{BindTo PathToProperty}
{BindTo Ancestor.typeOfAncestor.PathToProperty}
{BindTo Template.PathToProperty}
{BindTo #MyTextBox.Text}

Oto przykład uproszczenia wiązania metod. Przed:

// C# code
private ICommand _saveCommand;
public ICommand SaveCommand {
 get {
  if (_saveCommand == null) {
   _saveCommand = new RelayCommand(x => this.SaveObject());
  }
  return _saveCommand;
 }
}

private void SaveObject() {
 // do something
}

// XAML
{Binding Path=SaveCommand}

Po:

// C# code
private void SaveObject() {
 // do something
}

// XAML
{BindTo SaveObject()}

Możesz znaleźć bibliotekę tutaj: http://www.simplygoodcode.com/2012/08/simpler-wpf-binding.html

Uwaga W przykładzie 'BEFORE', którego używam do wiązania metod, że kod był już zoptymalizowany za pomocą RelayCommand, który ostatnio sprawdzałem nie jest natywną częścią WPF. Bez tego przykład "przed" byłby jeszcze dłuższy.

 13
Author: Luis Perez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-06 18:12:51

Kilka przydatnych fragmentów:

Oto Jak to zrobić głównie w kodzie:

Binding b = new Binding();
b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, this.GetType(), 1);
b.Path = new PropertyPath("MyElementThatNeedsBinding");
MyLabel.SetBinding(ContentProperty, b);

W dużej mierze skopiowałem to z powiązanie Źródła względnego w kodzie za.

Również strona MSDN jest całkiem dobra, jeśli chodzi o przykłady: Klasa RelativeSource

 11
Author: Nathan Cooper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-19 09:23:32

I just posted inne rozwiązanie za dostęp do DataContext elementu nadrzędnego w Silverlight, który działa dla mnie. Używa Binding ElementName.

 10
Author: Juve,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:01

To jest przykład użycia tego wzorca, który działał dla mnie na pustych datagridach.

<Style.Triggers>
    <DataTrigger Binding="{Binding Items.Count, RelativeSource={RelativeSource Self}}" Value="0">
        <Setter Property="Background">
            <Setter.Value>
                <VisualBrush Stretch="None">
                    <VisualBrush.Visual>
                        <TextBlock Text="We did't find any matching records for your search..." FontSize="16" FontWeight="SemiBold" Foreground="LightCoral"/>
                    </VisualBrush.Visual>
                </VisualBrush>
            </Setter.Value>
        </Setter>
    </DataTrigger>
</Style.Triggers>
 8
Author: Edd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-29 13:59:41

Nie przeczytałem każdej odpowiedzi, ale chcę tylko dodać tę informację w przypadku względnego powiązania komend źródłowych przycisku.

Kiedy używasz względnego źródła z Mode=FindAncestor, Wiązanie musi wyglądać następująco:

Command="{Binding Path=DataContext.CommandProperty, RelativeSource={...}}"

Jeśli nie dodasz DataContext do ścieżki, w czasie wykonywania nie będzie on w stanie odzyskać właściwości.

 8
Author: Kevin VDF,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-18 10:46:55

Jeśli element nie jest częścią drzewa wizualnego, RelativeSource nigdy nie będzie działać.

W tym przypadku musisz spróbować innej techniki, zapoczątkowanej przez Thomasa Levesque ' a.

Ma rozwiązanie na swoim blogu pod [WPF] jak powiązać dane, gdy DataContext nie jest dziedziczony. I to działa absolutnie genialnie!

W mało prawdopodobnym przypadku, gdy jego blog jest wyłączony, Dodatek A zawiera lustrzaną kopięjego artykułu .

proszę nie komentarz tutaj, proszę komentarz bezpośrednio na jego blogu post .

Dodatek A: Lustro postu na blogu

Właściwość DataContext w WPF jest bardzo przydatna, ponieważ jest automatycznie dziedziczona przez wszystkie dzieci elementu, do którego ją przypisujesz; dlatego nie musisz ustawiać jej ponownie na każdym elemencie, który chcesz powiązać. Jednak w niektórych przypadkach DataContext nie jest dostępny: dzieje się tak dla elementów, które nie są częścią drzewa graficznego lub logicznego. Może być bardzo trudno więc powiązać właściwość na tych elementach ...

Zilustrujmy prostym przykładem: chcemy wyświetlić listę produktów w DataGrid. W siatce chcemy być w stanie pokazać lub ukryć kolumnę ceny, na podstawie wartości właściwości ShowPrice wystawionej przez model widoku. Oczywistym podejściem jest powiązanie widoczności kolumny z właściwością ShowPrice:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding ShowPrice,
                Converter={StaticResource visibilityConverter}}"/>

Niestety zmiana wartości ShowPrice nie ma wpływu, a kolumna jest zawsze widoczna ... dlaczego? Jeśli spojrzymy na okno wyjściowe w Visual Studio, zauważymy następujący wiersz:

System.Okna.Data Error: 2: Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path = ShowPrice; DataItem=null; elementem docelowym jest 'DataGridTextColumn' (HashCode=32685253); właściwością docelową jest ' Visibility '(Typ'Visibility')

Wiadomość jest dość tajemnicza, ale znaczenie jest w rzeczywistości dość proste: WPF nie wie, który Framework do użycia w celu uzyskania DataContext, ponieważ kolumna nie należy do wizualnego lub logicznego drzewa DataGrid.

Możemy spróbować dostosować powiązanie, aby uzyskać pożądany rezultat, na przykład ustawiając RelativeSource na DataGrid:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding DataContext.ShowPrice,
                Converter={StaticResource visibilityConverter},
                RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"/>

Lub możemy dodać pole wyboru powiązane z ShowPrice i spróbować powiązać widoczność kolumny z właściwością IsChecked, podając nazwę elementu:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding IsChecked,
                Converter={StaticResource visibilityConverter},
                ElementName=chkShowPrice}"/>

Ale żadne z tych obejść nie wydaje się działać, my zawsze uzyskaj ten sam wynik ...

W tym momencie wydaje się, że jedynym realnym podejściem będzie zmiana widoczności kolumn w kodzie-behind, której zwykle wolimy unikać, używając wzorca MVVM... ale nie zamierzam się tak szybko poddawać, przynajmniej Nie, gdy są inne opcje do rozważenia

Rozwiązanie naszego problemu jest w rzeczywistości dość proste i wykorzystuje klasę Freezable. Podstawowym celem tej klasy jest definiowanie obiektów, które mają modyfikowalne i stan tylko do odczytu, ale interesującą cechą w naszym przypadku jest to, że obiekty Freezable mogą dziedziczyć DataContext nawet wtedy, gdy nie znajdują się w wizualnym lub logicznym drzewie. Nie znam dokładnego mechanizmu, który umożliwia takie zachowanie, ale wykorzystamy go, aby nasze Wiązanie działało ... ]}

Chodzi o stworzenie klasy (nazwałem ją BindingProxy z powodów, które powinny stać się oczywiste bardzo szybko), która dziedziczy Freezable i deklaruje właściwość zależności danych:

public class BindingProxy : Freezable
{
    #region Overrides of Freezable

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    #endregion

    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}

Możemy następnie zadeklaruj instancję tej klasy w zasobach DataGrid i powiązaj właściwość Data z bieżącym DataContext:

<DataGrid.Resources>
    <local:BindingProxy x:Key="proxy" Data="{Binding}" />
</DataGrid.Resources>

Ostatnim krokiem jest określenie tego obiektu BindingProxy (łatwo dostępnego za pomocą StaticResource) jako źródła wiązania:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding Data.ShowPrice,
                Converter={StaticResource visibilityConverter},
                Source={StaticResource proxy}}"/>

Zauważ, że ścieżka wiązania została poprzedzona prefiksem "Data", ponieważ ścieżka jest teraz względem obiektu BindingProxy.

Powiązanie teraz działa poprawnie, a kolumna jest prawidłowo pokazana lub Ukryta na podstawie na wystawie nieruchomości.

 3
Author: Contango,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-05 10:46:12