2009-06-26 17 views
10

Mam przycisk w moim formularzu, który powinien być włączony tylko po wybraniu elementu w widoku drzewa (lub widoku listy w tabitem). Po wybraniu elementu jego wartość jest przechowywana w zmiennej składowej łańcuchowej.Bindowanie danych WPF: włączyć/wyłączyć sterowanie na podstawie zawartości var?

Czy mogę powiązać właściwość IsEnabled przycisku z zawartością elementu var? Oznacza to, że jeśli element var nie jest pusty, włącz przycisk.

Podobnie, gdy zawartość elementu zmienia się (ustawiona lub usunięta), stan przycisku powinien się zmienić.

Odpowiedz

11

Ponieważ prawdopodobnie chcesz powiązać właściwość IsEnabled przycisku na podstawie ciągu znaków, spróbuj zrobić dla niego konwerter.

Ie ...


<StackPanel> 
<StackPanel.Resources> 
<local:SomeStringConverter mystringtoboolconverter /> 
</StackPanel.Resources> 
<Button IsEnabled="{Binding ElementName=mytree, Path=SelectedItem.Header, Converter={StaticResource mystringtoboolconverter}}" /> 
<StackPanel> 

i konwerter:

 

[ValueConversion(typeof(string), typeof(bool))] 
    class SomeStringConverter : IValueConverter { 
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { 
      string myheader = (string)value; 
      if(myhead == "something"){ 
       return true; 
      } else { 
       return false; 
      } 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { 
      return null; 
     } 
    } 
 

EDIT: Ponieważ PO chciała wiązać się zmiennej, coś w tym musi być zrobione:

 

public class SomeClass : INotifyPropertyChanged { 
    private string _somestring; 

    public string SomeString{ 
    get{return _somestring;} 
    set{ _somestring = value; OnPropertyChanged("SomeString");} 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    protected void OnPropertyChanged(string propertyName) 
     { 
      if (this.PropertyChanged != null) 
      { 
       this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 

} 
 

Następnie zmień powyższe wyrażenie wiążące na:

 
{Binding Path=SomeString, Converter={StaticResource mystringtoboolconverter}} 

Uwaga, MUSISZ wdrożyć INotifyPropertyChanged, aby zaktualizować swój interfejs użytkownika.

+0

Dzięki za odpowiedź. Dostaję błąd w moim XAML na tej linii: "Typ lokalu: StringToBoolConverter nie został znaleziony." StringToBoolConverter to nazwa mojej klasy konwertera. Czy muszę zakwalifikować go za pomocą przestrzeni nazw? – Number8

+0

Mam to. Problem z przestrzenią nazw w Xaml. – Number8

+0

Hmm. Myślę, że jest to niepełne; wygląda na to, że musi istnieć jakieś zdarzenie wywołane przez właściwość elementu, na którą odpowiada przycisk, więc gdy właściwość członka zostanie zmieniona, stan przycisku Enabled zmieni się. – Number8

6

Czy masz ViewModel utrzymywanie właściwości ciąg ustawiony jako DataContext widoku, w którym próbujesz zrobić to powiązanie?

Następnie dodaje zadziała:

// Example ViewModel 
public class MyClass : INotifyPropertyChanged 
{ 
    private string text; 

    public string Text 
    { 
     get { return text; } 
     set 
     { 
      text = value; 
      UpdateProperty("Text"); 
      UpdateProperty("HasContent"); 
     } 
    } 

    public bool HasContent 
    { 
     get { return !string.IsNullOrEmpty(text); } 
    } 


    public event PropertyChangedEventHandler PropertyChanged; 

    protected void UpdateProperty(string name) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(name)); 
    } 
} 

Następnie należy zrobić coś takiego w kodzie za zdania:

this.DataContext = new MyClass(); 

a przykład Xaml:

<StackPanel> 
     <TextBox Text="{Binding Text, UpdateSourceTrigger=PropertyChanged}" /> 
     <Button IsEnabled="{Binding HasContent}"> 
      Click Me! 
     </Button> 
    </StackPanel> 
+0

Właściwość string znajduje się w mojej głównej klasie okna. Czy jest jakiś sposób, aby to działało w tym przypadku? W tej chwili metoda HasContent() nie jest wywoływana; Podejrzewam, że ma to związek z tym, że DataContext nie jest ustawiony. – Number8

+0

Co powoduje, że przycisk wywołuje funkcję HasContent() w celu ustawienia jej stanu? Ponadto nie mam kontroli, która pobiera wartość ciągu. Czy IsEnabled potrzebuje atrybutu UpdateSourceTrigger? – Number8

+0

Jeśli okno ma te właściwości, można ustawić go jako własny tekst danych, taki jak: this.DataContext = this w Windows Loaded-Event. Jest to jednak bardzo zła praktyka. Powinieneś rozważyć posiadanie ViewModel jak w moim próbnym zestawie jako DataContext. Uwaga: HasContent nie jest metodą, jej właściwością, ponieważ tylko Właściwości mogą być powiązane z widokiem. Jego wynik jest oceniany za każdym razem, gdy podnosisz właściwość PropertyChanged o konkretną nazwę właściwości. Funkcja UpdateSourceTrigger jest potrzebna głównie w TextBoxach do zapisania zmian w tekście do powiązanej właściwości za pomocą każdego wpisanego klawisza. Inaczej robią to z powodu utraty koncentracji – Andrej

Powiązane problemy