2013-03-09 1 views
0

У моего представления есть 2 кнопки под названием BrowseButton и UploadButton.Использование IValueConverter для включения/выключения свойства IsDefault кнопки

BrowseButton is default и UploadButton нет. Моя цель - изменить значение по умолчанию после нажатия кнопки «Обзор» (т. Е. BrowseButton не является значением по умолчанию, а UploadButton).

При нажатии на кнопку BrowseButton отображается свойство (строка) в моей модели ViewModel. Это означает, что я могу привязать это свойство и передать значение этого свойства моему IValueConverter и вернуть либо true, либо false. Это работает по желанию.

Мой BoolConverter выглядит

public class BoolConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      if (value == null || string.IsNullOrEmpty(System.Convert.ToString(value))) 
       return false; 

      return true; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 
    } 

И мой Xaml

<Button Content="Browse for file" Width="150" Margin="5" Command="{Binding BrowseForFileCommand}" IsDefault="{Binding File, Converter={StaticResource BConverter}}" /> 
<Button Content="Upload" Width="75" Margin="5" Command="{Binding UploadCommand}" IsDefault="{Binding File, Converter={StaticResource BConverter}}" /> 

Проблема заключается в том, они оба связывают к тому же классу BoolConverter и, как таковые, оба равны (т.е. если один ложно, то оба ложные!). Опять же, я могу понять, почему.

Мой вопрос: как мне обойти это? Это действительно просто случай наличия нескольких классов конвертеров?

EG

public class BoolConverterForThis : IValueConverter 
{//implementation} 
public class BoolConverterForThat : IValueConverter 
{//implementation} 
public class BoolConverterForOther : IValueConverter 
{//implementation} 
+0

почему бы не определить два свойства BOOL в вашей ViewModel как 'CanUpload',' CanBrowse' и привязывать напрямую? –

+0

Я думал об этом, но было неправильно использовать ViewModel для функции пользовательского интерфейса; Я чувствовал, что ViewModel должен хранить данные только. Это неправильно? – Dave

ответ

1

Я был бы соблазн сделать что-то вроде этого:

public class StringIsEmptyToBoolConverter : MarkupExtension, IValueConverter 
{ 
    public StringIsEmptyToBoolConverter() 
    { 
     this.Result = false; 
    } 

    public bool Result { get; set; } 

    public object Convert(object value, Type targetType, 
          object parameter, CultureInfo culture) 
    { 
     return string.IsNullOrEmpty(value as string) ? this.Result : !this.Result; 
    } 

    public object ConvertBack(object value, Type targetType, 
           object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     return this; 
    } 
} 

, которые вы могли бы использовать в вас Xaml так:

<Window.Resources> 
    <wpfApplication2:StringIsEmptyToBoolConverter 
     x:Key="TrueResultConverter" Result="True"/> 
    <wpfApplication2:StringIsEmptyToBoolConverter 
     x:Key="FalseResultConverter" Result="False"/> 
</Window.Resources> 
<Grid> 
    <!-- because the converter derives from MarkupExtension you can 
     create an instance directly instead of creating a resource --> 
    <Button IsDefault="{Binding File, 
      Converter={wpfApplication2:StringIsEmptyToBoolConverter Result=True}}"/> 

    <!-- or use a resource --> 
    <Button IsDefault="{Binding File, 
      Converter={StaticResource TrueResultConverter}}"/> 
    <Button IsDefault="{Binding File, 
      Converter={StaticResource FalseResultConverter}}"/> 
</Grid> 
+0

Спасибо, Фил. Мне нравится это из-за его повторного использования, я чему-то научился, и он отлично работает! Спасибо. – Dave

+0

Дальнейшее чтение на MarkupExtension, если оно полезно для любого: http://msdn.microsoft.com/en-gb/library/ms747254.aspx – Dave

+0

на основе вашего ответа, могу ли я предположить, что типично иметь несколько классов конвертера (вместо того, чтобы пытаться создать 1 «богоподобный» класс, чтобы справиться со всем)? – Dave

0

У меня была такая же проблема, и мне пришлось прибегнуть к кодированию Истинного видимости конвертер и конвертер ложных Visiility. Не то, чтобы вы не могли закодировать конвертер видимости, но в интересах кого-то, кто этого не делает, так выглядел мой код.

public class TrueVisibilityConverter : IValueConverter 
{ 
    public object Convert(
     object value, 
     Type targetType, 
     object parameter, 
     CultureInfo culture) 
    { 
     bool visibility = (bool)value; 
     return visibility ? Visibility.Visible : Visibility.Collapsed; 
    } 

    public object ConvertBack(
     object value, 
     Type targetType, 
     object parameter, 
     CultureInfo culture) 
    { 
     Visibility visibility = (Visibility)value; 
     return (visibility == Visibility.Visible); 
    } 
} 



public class FalseVisibilityConverter : IValueConverter 
    { 
     public object Convert(
      object value, 
      Type targetType, 
      object parameter, 
      CultureInfo culture) 
     { 
      bool visibility = (bool)value; 
      return visibility ? Visibility.Collapsed:Visibility.Visible ; 
     } 

     public object ConvertBack(
      object value, 
      Type targetType, 
      object parameter, 
      CultureInfo culture) 
     { 
      Visibility visibility = (Visibility)value; 
      return (visibility == Visibility.Collapsed); 
     } 
    } 

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

  • Нет связанных вопросов^_^