2008-11-25 7 views
6

Po prostu zdałem sobie sprawę, że wymuszam właściwości wiązania/zależności i naprawdę nie rozumiem w pełni koncepcji.WPF DependencyProperties

Herezje właściwość zależność:

public string Problem 
{ 
    get { return (string)GetValue(ProblemProperty); } 
    set { SetValue(ProblemProperty, value); } 
} 

public static readonly DependencyProperty ProblemProperty = 
    DependencyProperty.Register(
    "Problem", 
    typeof(string), 
    typeof(TextBox)); 

XAML jest tak:

<TextBlock Text="{Binding Path=Problem}"/> 

mam ręcznie ustawiając właściwość Problem do wartości w konstruktorze obiektu, ale nie robi” t odpowiednio zaktualizuj TextBlock. . . jakieś pomysły? Próbowałem Mode="OneWay" i Mode="TwoWay" na powiązanie i nadal nie działa.

Myślałem, że to powinno działać automatycznie? Czy zasadniczo mam coś złego?

Dzięki

+0

Wszystko wygląda dobrze dla mnie. Musi to być twój "DataContext". Jak to ustawiasz? –

Odpowiedz

11

Problem Twojego posiadające jest zdecydowanie związany z DataContext. Rozszerzenie {Binding} musi wiedzieć, gdzie znajduje się nieruchomość, do której się zobowiązujesz. Domyślną lokalizacją, którą przegląda, są elementy DataContext, które domyślnie są zawsze ustawiane na DataContext tego elementu nadrzędnego. Jeśli przechodzisz DataContext w górę drzewa logicznego do okna nadrzędnego, DataContext będzie mieć wartość NULL (ponieważ DataContext twojego okna ma wartość NULL). Dlatego Twój {Binding} na twoim bloku tekstowym mówi "Właściwość Bind my Text do roperty mojego DataContext ..., która jest zerowa."

Istnieje kilka sposobów na rozwiązanie tego problemu. Jobi wymienić i ustawić właściwość element Ciebie wiążące, aby wskazać okno, w którym DependencyProperty jest zdefiniowany następująco:.

<TextBlock Text="{Binding Path=Problem,ElementName=_window}" /> 

Innym rozwiązaniem byłoby, aby ustawić DataContext okno zwrócić na siebie w ten sposób wszystkie elementy zawarte w jego zawartości będą miały DataContext okna.

<Window .... 
     DataContext="{Binding RelativeSource={RelativeSource Self}}"> 

Teraz w każdej chwili trzeba wiążący do właściwości zdefiniowanych w oknie (jak swojej własności zależności problem), a następnie można po prostu to zrobić:

<TextBlock Text="{Binding Problem}" /> 
+0

Rozwiązanie polegające na ustawieniu datacontekstu okna, które samo dla mnie nie działa. Działa tylko wtedy, gdy ustawiam datakekst dla elementu o jeden poziom niżej lub więcej (pierwsza siatka działa) do okna. Czy to jest oczekiwane? – Erik83

0

Jego Okno to znajduje się w

public partial class Window1 : Window 
{ 
    public string Problem 
    { 
     get { return (string)GetValue(ProblemProperty); } 
     set { SetValue(ProblemProperty, value); } 
    } 

    public static readonly DependencyProperty ProblemProperty = 
        DependencyProperty.Register(
        "Problem", 
        typeof(string), 
        typeof(Window1)); 


    public Window1() 
    { 
     InitializeComponent(); 

     Problem = "ifowiof"; 
    } 

    public void OnClick(object sender, EventArgs e) 
    { 
     Problem = "behl"; 
    } 

    public void OnCancel(object sender, EventArgs e) 
    { 
     Problem = "eioeopje"; 
    } 
} 
.

XAML:

<Window x:Class="WpfToolTip.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
     <StackPanel> 
      <Button Click="OnClick" Content="OK" /> 
      <Button Click="OnCancel" Content="Cancel" /> 
      <TextBlock Text="{Binding Path=Problem}" /> 
    </StackPanel> 
</Window> 

It działa, jeśli ustawię RelativeSource tak, jak powiedziałeś przy ładowaniu, ale jeśli ręcznie zmieniam właściwość Problem w kodzie (np. przez kliknięcie przycisku) nigdy nie aktualizuje TextBlock z nową wartością.

+0

Czy kiedykolwiek znalazłeś odpowiedź na to pytanie? Mam podobny problem. Wygląda na to, że powiązanie zostanie utracone po ustawieniu właściwości problemu. Nie jestem pewien, jaka jest poprawna procedura aktualizacji wartości w ten sposób. –

2

Możesz użyć ElementName Binding tutaj, element będzie samym oknem.

<Window x:Class="WpfToolTip.Window1" 
x:Name="_window" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <StackPanel> 
     <Button Click="OnClick" Content="OK" /> 
     <Button Click="OnCancel" Content="Cancel" /> 
     <TextBlock Text="{Binding Path=Problem,ElementName=_window}" /> 
</StackPanel> 

0

W kodzie zarejestrowaniu Dependency obiekt dla TextBox klasy (ostatnia linia cytatu).

public static readonly DependencyProperty ProblemProperty =
DependencyProperty.Register (
"problem",
typeof (string),
typeof (TextBox));

więc można ustawić wartość dla ProblemProperty tylko dla pól tekstowych, ale nie mogę znaleźć żadnego tekstowe w każdym z fragmentów kodu. Powinieneś zarejestrować swoją właściwość zależności dla typu, do którego przypisana jest wartość, z twojej próbki właściwy wybór nie jest dla mnie oczywisty. Można, tak jak Micheasz, zdefiniować, że jest to DP okna, a następnie ustawić właściwość w swoim okienku. Albo można zdefiniować go do dowolnej nazwie obiektu zależności wewnątrz okna, czyli jakiegoś przedmiotu z name = m_ContentElement, a następnie ustaw wiązania się
{Binding ElementName=m_ContentElement, Path=Problem}
lub krócej:
{Binding Problem, ElementName=m_ContentElement}

0

Istnieją dwa sposoby, aby zrozumieć powód problemu, który opisałeś.

Na początku - powinieneś spróbować ustawić zmieniony handler właściwości (w deklaracji właściwości zależności) i umieścić tam punkt przerwania. Zobaczysz, czy twoja nieruchomość się zmienia, czy nie.

Na sekundę - należy sprawdzić typ właściwości właściwości zależności.

Czy mógłbyś pokazać pełne Xaml i kodbehind?

2

Wypróbuj typeof(object) zamiast typeof(string).