2012-06-06 5 views
2

У меня есть некоторые элементы управления, которые мне нужно скрыть или отключить на основе результатов некоторых вычислений. Я хотел бы привязать свойство IsEnabled или IsVisible к результату получения какого-либо метода или свойства родительского класса формы. Что-то вроде этого:Как связать свойство IsEnabled или IsVisible с методом или свойством get?

<TabItem Name="MyTab" Header="This should be enabled when result is 2" IsEnabled="{Binding MyMethod}"> 
    <!--Some other stuff--> 
</TabItem> 

и в коде позади:

public bool MyMethod() 
{ 
    return _valueA + _valueB == 2; 
} 

Можете ли вы помочь мне найти правильный путь для достижения этой цели, пожалуйста?

Thx, JiKra

+0

Откуда возникают _valueA и _valueB и когда они должны быть пересчитаны? –

+0

Они могут быть глобальными переменными текущего класса, или может быть назначен какой-то внешний класс калькулятора - это не имеет значения. Мне просто нужно привязать свойство IsEnabled к методу, подобному этому, или к свойству класса. – JiKra

ответ

3

Вам может понадобиться использовать MultiBinding:

<TabItem Name="MyTab" Header="This should be enabled when result is 2"> 
    <TabItem.IsEnabled> 
    <MultiBinding Converter={StaticResource MyAddConverter}> 
     <Binding Path=ValueA UpdateSourceTrigger=PropertyChanged /> 
     <Binding Path=ValueB UpdateSourceTrigger=PropertyChanged /> 
    </MultiBinding> 
    </TabItem.IsEnabled> 
    <!--Some other stuff--> 
</TabItem> 

В вашем ViewModel, вы должны иметь следующее (предполагается, что ваш ViewModel реализует INotifyPropertyChanged):

public double ValueA 
{ 
    get { return _valueA; } 
    set 
    { 
    _valueA = value; 
    OnPropertyChanged("ValueA"); 
    } 
} 

И то же самое для ValueB, что позволит WPF обновлять Binding каждый раз либо ValueA или ValueB изменения

Ваш преобразователь должен выглядеть следующим образом:

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
{ 
    double valueA = (double)values[0]; 
    double valueB = (double)values[1]; 
    return valueA + valueB == 2; 
} 

Это позволит вам иметь один внешний метод, определенный в конвертер, который будет вызываться снова каждый раз, когда значение а или изменится VALUE млрд.

Я бы сказал, что это все, что нужно =)

+0

ОК, это действительно хорошо. Я знаю о конвертерах. Но вопрос моего вопроса заключался в том, возможно ли связать IsEnabled (или любое) свойство компонентов с локальным методом или свойством класса. valueA и valueB не имеют значения, это был просто пример. Я новичок в WPF, не обвиняйте меня, пожалуйста. Итак, вы можете показать мне самый простой способ привязки IsEnabled к локальному методу или свойству класса, например. действительно dummy prop like: public bool IsItEnabled() {return true; }? – JiKra

+0

Обычно вы можете привязываться к свойствам. Вы можете сделать следующее: 'public bool IsIsEnabled {get {return true; }} ', и это будет легко соответствовать тому, что вам нужно. Хорошей практикой в ​​WPF для привязки к методам является использование конвертера (или обходного пути чуть выше). Я считаю, что есть несколько способов сделать это, но я не смотрел на него, потому что конвертеры делают то, что мне нужно, и их легче поддерживать. – Damascus

+0

Ниже перечислены некоторые обходные пути: http://stackoverflow.com/questions/502250/bind- to-a-method-in-wpf, если вам действительно нужно привязываться к методу – Damascus

1

Вы не можете связываться с методом непосредственно. Это должно быть свойство. С учетом сказанного есть некоторые другие трюки, связанные с методом, показанным в этом вопросе Bind to a method in WPF?.

На ваш вопрос, что бы я сделал, это сделать свойство MyMethod.

public double SumAB 
{ 
    get{ return _valueA + _valueB;} 
} 

Затем добавить конвертер для вашего связывания:

<TabItem Name="MyTab" Header="This should be enabled when result is 2" IsEnabled="{Binding SumAB, Converter={StaticResource SumValueToBoolConverter}}"> 

Ваш конвертер код будет выглядеть следующим образом:

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
{ 
    double sumValue = (double)value; 
    if(sumValue==2) 
    { 
     return true; 
    } 
    return false; 
} 
2

Вам нужно создать новое свойство, представляющее значение вы пытаясь достичь здесь. Это целая цель модели представления. Я настоятельно рекомендую вам избегать использования конвертера здесь, хотя он будет работать. Преобразователи должны использоваться для обработки проблем, связанных только с просмотром, тогда как это относится к виду состояния.

Потенциальный вид модели будет выглядеть следующим образом: (Я использую мой BindableBase)

class AddingViewModel : BindableBase { 
    private int _valueA; 
    public int ValueA { 
     get { return _valueA; } 
     set { SetProperty(ref _valueA, value, "ValueA", OnValueAChanged); } 
    } 

    private void OnValueAChanged() { UpdateIsTabEnabled(); } 

    private int _valueB; 
    public int ValueB { 
     get { return _valueB; } 
     set { SetProperty(ref _valueB, value, "ValueB", OnValueBChanged); } 
    } 

    private void OnValueBChanged() { UpdateIsTabEnabled(); } 

    private bool _isTabeEnabled; 
    public bool IsTabEnabled { 
     get { return _isTabEnabled; } 
     private set { SetProperty(ref _isTabEnabled, value, "IsTabEnabled"); } 
    } 

    private void UpdateIsTabEnabled() { 
     IsTabEnabled = _valueA + _valueB == 2; 
    } 
} 

Это может показаться немного многословным, но я хотел бы выделить несколько причин для этого:

  • По мере изменения требований легко найти и изменить UpdateIsTabsEnabled.
  • Как ValueA и ValueB становятся компонентами других функций, легко добавить крючки в их уважаемые методы OnChanged.
  • Легко связывать IsTabEnabled либо IsEnabled, либо Visibility по желанию.
+0

Хорошая мысль о наличии условия обновления в ViewModel, а не в конвертере. –