2013-12-13 10 views
21

В моем приложении WPF я пытаюсь изменить видимость кнопки в зависимости от параметров, выбранных пользователем. При загрузке я хочу, чтобы одна из кнопок не была видимой. Я использую встроенный преобразователь значений BooleanToVisibilityConverter. Однако он не работает, когда кнопка появляется во время загрузки. Я изменил свойство как на true, так и на false, не имеет значения. Ниже мой код, я не вижу, что мне не хватает?WPF MVVM скрывает кнопку с помощью BooleanToVisibilityConverter

Свойство в моей модели Посмотреть

bool ButtCancel 
    { 
     get { return _buttCancel; } 
     set 
     { 
      _buttCancel = value; 
      OnPropertyChanged("ButtCancel"); 
     } 
    } 

В моей app.xaml

<Application.Resources>  
    <BooleanToVisibilityConverter x:Key="BoolToVis"/> 

В моей MainWindow.xaml

<Button Grid.Column="2" Command="{Binding CommandButtProgressCancel}" Content="Cancel" Visibility="{Binding ButtCancel, Converter={StaticResource BoolToVis}}" IsEnabled="{Binding ButtCancelEnabled}" Height="50" Width="120" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,50,20"/> 
+3

Является ли ваша собственность 'ButtCancel'' public'? Он не имеет модификатора доступа в выдержке кода, что сделает его «закрытым» и, таким образом, невидимым для механизма привязки. Кроме того, вы не должны связывать свойство IsEnabled; пусть кнопка использует обратный вызов вашей команды 'CanExecute' для определения своего собственного состояния. –

+0

@MikeStrobel, безусловно, модификатор доступа по умолчанию - 'internal', а не' private'. – Sheridan

+0

Да не могу поверить, я пропустил это! Он не был общедоступным. – mHelpMe

ответ

34

Для начала спариванию, если вы используете команда, тогда вам не нужно связывать IsEnabled, реализация этой команды должна решить это.

Во-вторых, связывание ViewModel к виду, как правило, происходят в немного более поздней стадии, так что лучше, чтобы также установить значение по умолчанию для связывания, как и

Visibility="{Binding ButtCancel, Converter={StaticResource BoolToVis}, FallbackValue=Hidden}" 

В-третьих, в качестве Майк отметил, что ваша собственность является общедоступной, поскольку ViewModel и View являются двумя отдельными классами.

+1

Свойство 'internal' также не будет работать. Механизм привязки не знает, где была объявлена ​​привязка, поэтому все непубличные члены обрабатываются одинаково (фактически «частный»). –

+0

О, я не знал об этом, спасибо Майку, я подстрою свой ответ. –

6

Вместо использования конвертера вы можете просто использовать DataTrigger.

<Button Grid.Column="2" Command="{Binding CommandButtProgressCancel}" Content="Cancel" 
    Visibility="{Binding ButtCancel, Converter={StaticResource BoolToVis}}" 
     IsEnabled="{Binding ButtCancelEnabled}" Height="50" Width="120" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,0,50,20"> 
    <Button.Style> 
     <Style TargetType={X:Type Button}> 
      <!-- This would be the default visibility --> 
      <Setter Property="Visibility" Value="Visible" /> 
      <Style.Triggers> 
       <DataTrigger Binding = "{Binding ButtCancel, UpdateSourceTrigger=PropertyChanged}" Value = "True"> 
        <Setter Property="Visibility" Value="Hidden" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </Button.Style> 
</Button> 

Update свойства вашего ViewModel, чтобы public

public bool ButtCancel 
    { 
     get { return _buttCancel; } 
     set 
     { 
      _buttCancel = value; 
      OnPropertyChanged("ButtCancel"); 
     } 
    } 

и убедитесь, что DataContext вашего MainWindow устанавливается в ViewModel.

+0

триггеры не самые лучшие, если вы пытаетесь использовать шаблон MVVM (как говорит OP). – 00jt

Смежные вопросы