【问题标题】:WPF Data Binding and FormattingWPF 数据绑定和格式化
【发布时间】:2010-11-18 22:19:57
【问题描述】:

我的 ViewModel 中有一个名为 IsConnected 的 bool 属性,我想将它绑定到我的 MainWindow 中的 TextBlock。而不是让文本块读取truefalse,我需要它说ConnectedDisconnected。原谅我,因为我是 WPF 新手。如果有人能给我一个先机,我可以从那里开始,但我不知道如何弄清楚我需要什么。

【问题讨论】:

    标签: wpf data-binding mvvm


    【解决方案1】:

    最简单的方法可能是创建一个自定义转换器,将您的布尔值转换为字符串。在任何地方搜索 IValueConverter 和/或 WPF。

    public class BoolToConnectedConverter : IValueConverter
    {
        #region IValueConverter Members
    
        public object Convert(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
           if((bool)value)
                 return "Connected";
           else
                 return "Disconnected";
        }
    
        public object ConvertBack(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    
        #endregion
    }
    

    添加 xmlns:

    xmlns:converter="clr-namespace:MyProjectNameSpace"
    

    向 XAML 添加资源(更改为所需的任何元素)

    <Window.Resources>
      <converter:BoolToConnectedConverter x:Key="connectedConverter" />
    </Window.Resources>
    

    在 XAML 中:

    <TextBlock Text={Binding IsConnected, Converter={StaticResource connectedConverter}" />
    

    【讨论】:

    • 对此我要做的唯一更改是从字符串资源文件中检索文本。这样你就可以使它成为一个很好的通用 BoolToString 转换器,并使用转换器参数传入要使用的资源键的前缀(前缀 + 布尔值 == 从资源中检索字符串所需的完整键)。
    • @slugster,我同意这一点。想了一会儿,但为了这个示例的简单性而放弃了它。
    • 我不喜欢价值转换器。它们是通常包含细微错误的黑匣子,除非您对其进行严格测试,否则这些错误不会出现。例如,如果它正在转换的值不是布尔值,则这个会引发异常。应该是?为什么不转换回来可以?答案是因为这不是真正的转换器。这是支持视图的一次性破解。您无法通过查看 XAML 来判断它正在使用的转换器是真正的转换器还是只是一种快速破解。一旦您的项目开始变大,这就会成为一个问题。
    【解决方案2】:

    我通常更喜欢只向视图模型添加一个属性(我真的不喜欢值转换器),但这里有一个简单的方法来完成你想要使用样式做的事情:

    <TextBlock>
      <TextBlock.Style>
        <Style TargetType="TextBlock">
          <Setter Property="Text" Value="Connected"/>
          <Style.Triggers>
            <DataTrigger Binding="{Binding IsConnected}" Value="False">
              <Setter Property="Text" Value="Disconnected"/>
            </DataTrigger>
          </Style.Triggers>
        </Style>
      </TextBlock.Style>
    </TextBlock>
    

    编辑

    请注意,一旦您习惯了使用数据触发器,您就可以对您的视图进行各种修改,而无需接触您的视图模型。例如:

    <StackPanel>
       <Image Source="images\connected.png">
         <Image.Style>
            <Style TargetType="Image">
               <Setter Property="Visibility" Value="Collapsed"/>
               <Style.Triggers>
                  <DataTrigger Binding="{Binding IsConnected}" Value="True">
                    <Setter Property="Visibility" Value="Visible"/>
                  </DataTrigger>
               </Style.Triggers>
            </Style>
         </Image.Style>
      </Image>
       <Image Source="images\disconnected.png">
         <Image.Style>
            <Style TargetType="Image">
               <Setter Property="Visibility" Value="Collapsed"/>
               <Style.Triggers>
                  <DataTrigger Binding="{Binding IsConnected}" Value="False">
                    <Setter Property="Visibility" Value="Visible"/>
                  </DataTrigger>
               </Style.Triggers>
            </Style>
         </Image.Style>
      </Image>
    </StackPanel>
    

    【讨论】:

    • 这似乎是解决问题的更好方法。我并不是真的认为转换器是一个好主意。样式似乎更合适,我不必创建辅助属性来生成字符串值。我宁愿将我的 ViewModel 数据保留为预期的数据。
    • 工作得很好,感谢图片示例,因为我想在我的视图中为另一个属性做类似的事情。
    【解决方案3】:

    使用 ViewModel,你编写了两个属性包装,并通知真实属性的变化。

    这样每当值改变时,你的字符串表示就会更新并绑定到控件,而你仍然可以在代码中使用 bool 属性。

    public string IsConnectedStr{
      get{
        return IsConnected?"Connected":"Disconnected";
      }
    }
    
    public bool IsConnected{
       get{
         return _isConnected;
       }
       set{
         _isConnected=value;
         PropertyChanged("IsConnected");
         PropertyChanged("IsConnectedStr");
       }
    }
    

    【讨论】:

      【解决方案4】:

      你可以通过两种方式做到这一点

      1) 写一个转换器

      2) 更改 ViewModel 中的函数,使其返回所需的字符串而不是布尔值

      最简单的方法是 #2,但如果你真的需要在代码中的其他地方使用 bool 值,你可以使用 #1(谷歌转换器和 wpf)

      【讨论】:

        【解决方案5】:

        看看价值转换器。

        http://www.wpftutorial.net/ValueConverters.html

        public class BoolToConnectedConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, 
                object parameter, CultureInfo culture)
            {
                var isConnected = (bool)value;
                return isConnected ? "Connected" : "Disconnected";
            }
        
            public object ConvertBack(object value, Type targetType, 
                object parameter, CultureInfo culture)
            {
                throw new NotImplementedException("Not required for read-only values");
            }
        }
        

        在您的 XAML 中:

        <Window.Resources>
            <l:BoolToConnectedConverter x:Key="boolToConnectedConverter" />
        </Window.Resources>
        <Grid>
            <Label Content="{Binding IsConnected, Converter={StaticResource boolToConnectedConverter}}" />
        </Grid>
        

        【讨论】:

          猜你喜欢
          • 2011-05-28
          • 2011-05-02
          • 2011-03-17
          • 2011-09-28
          • 2010-11-15
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多