2015-12-30 60 views
0

在当前项目中,我有一个对象列表。 其中2个属性的类型为string []。WPF在XAML中的对象列表中显示一个字符串数组

目前我可以显示其主要标识符的项目数量。 但除此之外,我想在指定的字符串[]中显示所有不同的字符串。

类看起来是这样的:

public class TimeStamp 
{ 
    public int ID { get; set; } 
    public string[] DaysOfWeek { get; set; } 
    public string[] HoursOfDay { get; set; } 
} 

在我的网页,我有以下

<ListView x:Name="listboxFolder1" Grid.Row="2" Margin="5" Grid.ColumnSpan="4" 
     ItemsSource="{Binding}"> 
     <ListView.ItemTemplate> 
      <DataTemplate> 
       <Border BorderBrush="Blue" Margin="3" Padding="3" BorderThickness="2" CornerRadius="0 25 0 25" Background="Beige" HorizontalAlignment="Stretch"> 
        <StackPanel Orientation="Horizontal"> 
         <Image Margin="10" Width="50" Height="50" Stretch="Fill" Source="/Images/watch.png"> 
          <Image.BitmapEffect> 
           <DropShadowBitmapEffect /> 
          </Image.BitmapEffect> 
         </Image> 
         <StackPanel Orientation="Vertical" VerticalAlignment="Center"> 
          <TextBlock Text="{Binding ID}"/> 
          <TextBlock Text="{Binding DaysOfWeek}"/> 
         </StackPanel> 
        </StackPanel> 
       </Border> 
      </DataTemplate> 
     </ListView.ItemTemplate> 
    </ListView> 

而完成,绑定的设置(如上述工作):

static List<iBackupModel.Models.TimeStamp> mySchedules { get; set; } 
    public Scheduler() 
    { 
     InitializeComponent(); 
     listboxFolder1.ItemsSource = Home.mySettings.TimeStamps; 
    } 

但DaysOfWeek得到显示像:String [] - 矩阵。

我希望它是像“星期一|星期五|星期日”。

如果可以将它与一个固定的集合(在本例中是所有工作日)进行匹配并对所有缺失的项目进行删减操作,那将会很棒,但是我已经对第一个项目感到满意了。

这可能吗?

对于第一个和第二个选项?

任何帮助更受欢迎。 在此先感谢。

回答

1

我基本同意他的做法devuxer。另一方面,如果你想保留你的模型类,覆盖第二个问题的最简单方法是将字符串数组中的转换器添加到TextDecorations中。

[ValueConversion(typeof(string[]), typeof(TextDecorations))] 
public class DecorationsConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     var source = value as string[]; 
     if (source == null) 
      return DependencyProperty.UnsetValue; 

     return source.Contains(parameter as string) ? null : TextDecorations.Strikethrough; 
    } 

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

并改变ListView使用该转换器。

<ListView x:Name="listboxFolder1" Grid.Row="2" Margin="5" Grid.ColumnSpan="4"> 
    <ListView.Resources> 
     <local:DecorationsConverter x:Key="DecorationsConverterKey"/> 
    </ListView.Resources> 
    <ListView.ItemTemplate> 
     <DataTemplate> 
      <Border BorderBrush="Blue" Margin="3" Padding="3" BorderThickness="2" CornerRadius="0 25 0 25" Background="Beige" HorizontalAlignment="Stretch"> 
       <StackPanel Orientation="Horizontal"> 
        <Image Margin="10" Width="50" Height="50" Stretch="Fill" Source="/Images/watch.png"> 
         <Image.BitmapEffect> 
          <DropShadowBitmapEffect /> 
         </Image.BitmapEffect> 
        </Image> 
        <StackPanel Orientation="Vertical" VerticalAlignment="Center"> 
         <TextBlock Text="{Binding ID}"/> 
         <TextBlock> 
          <Run Text="Sunday" 
           TextDecorations="{Binding DaysOfWeek, Converter={StaticResource DecorationsConverterKey}, ConverterParameter=Sunday}"/> 
          <Run Text="|"/> 
          <Run Text="Monday" 
           TextDecorations="{Binding DaysOfWeek, Converter={StaticResource DecorationsConverterKey}, ConverterParameter=Monday}"/> 
          <Run Text="|"/> 
          <Run Text="Tuesday" 
           TextDecorations="{Binding DaysOfWeek, Converter={StaticResource DecorationsConverterKey}, ConverterParameter=Tuesday}"/> 
          <Run Text="|"/> 
          <Run Text="Wednesday" 
           TextDecorations="{Binding DaysOfWeek, Converter={StaticResource DecorationsConverterKey}, ConverterParameter=Wednesday}"/> 
          <Run Text="|"/> 
          <Run Text="Thursday" 
           TextDecorations="{Binding DaysOfWeek, Converter={StaticResource DecorationsConverterKey}, ConverterParameter=Thursday}"/> 
          <Run Text="|"/> 
          <Run Text="Friday" 
           TextDecorations="{Binding DaysOfWeek, Converter={StaticResource DecorationsConverterKey}, ConverterParameter=Friday}"/> 
          <Run Text="|"/> 
          <Run Text="Saturday" 
           TextDecorations="{Binding DaysOfWeek, Converter={StaticResource DecorationsConverterKey}, ConverterParameter=Saturday}"/> 
         </TextBlock> 
        </StackPanel> 
       </StackPanel> 
      </Border> 
     </DataTemplate> 
    </ListView.ItemTemplate> 
</ListView> 
+0

这正是我所需要的,谢谢你的回答。 –

+0

不客气。这是脱离主题,但我认为最好将DaysOfWeek属性的类型从字符串数组更改为System.DayOfWeek枚举数组以更安全地匹配。 – emoacht

3

问题是,您正在将TextBlockText财产绑定到string[]而不是string

内部发生的是WPF调用DaysOfWeek字符串数组上的ToString()方法,这会导致“System.String []”。你想要的是绑定到string.Join("|", DaysOfWeek })

有多种方法可以做到这一点。强烈推荐的方法是创建一个“视图模型”,用于保存您实际想要的数据,而不是数据库或某种其他类型模型的数据。

所以,你可以创建一个TimeStampViewModel,它看起来像这样:

public class TimeStampViewModel 
{ 
    public int Id { get; set; } 
    public string DaysOfWeek { get; set; } 
    public string HoursOfDay { get; set; } 

    public TimeStampViewModel(int id, string[] daysOfWeek, string[] hoursOfDay) 
    { 
     Id = id; 
     DaysOfWeek = string.Join("|", daysOfWeek); 
     HoursOfDay = string.Join("|", hoursOfDay); 
    } 
} 

然后,而不是结合TimeStamp对象绑定到TimeStampViewModel对象,你在后面的类代码中创建,像这样:

TimeStampViewModels = timeStamps 
    .Select(x => new TimeStampViewModel(x.Id, x.DaysOfWeek, x.HoursOfDay)) 
    .ToList(); 

这假设你在你的代码隐藏中有一个属性public List<TimeStampViewModel> TimeStampViewModels { get; set; }

如果您想了解有关视图模型的更多信息,我建议您阅读Model-View-ViewModel(MVVM)模式。这里作为article published by Microsoft让你开始。许多人认为MVVM是WPF(和其他基于XAML的框架)编程的最佳实践。


要处理关于删除线的“额外信用”问题,这将变得更加棘手。您需要修改您的视图模式是这样的:

public class TimeStampViewModel 
{ 
    public int Id { get; set; } 
    public List<OptionalDayOfWeek> DaysOfWeek { get; set; } 
    public string HoursOfDay { get; set; } 

    public TimeStampViewModel(int id, string[] daysOfWeek, string[] hoursOfDay) 
    { 

     Id = id; 
     DaysOfWeek = 
      new[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" } 
      .GroupJoin(daysOfWeek, day => day, dayOfWeek => dayOfWeek, (day, matches) => new OptionalDayOfWeek { DayOfWeek = day, IsAvailable = matches.Any() }) 
      .ToList(); 
     HoursOfDay = string.Join("|", hoursOfDay); 
    } 
} 

public class OptionalDayOfWeek 
{ 
    public string DayOfWeek { get; set; } 
    public bool IsAvailable { get; set; } 
} 

同时,你的XAML将需要出示星期的日子里像一个ItemsControl,其中每个项目被绑定到一个OptionalDayOfWeek。然后,您可以使用IValueConverter来确定TextDecorations是否应包含Strikethrough或不包含。 (对不起,我没有时间来写这个部分的那一刻,但我希望这是足够的暗示上手。)

+0

我已经考虑过这个解决方案,但在模型前放置另一个类似乎至少是不合逻辑的。在每次更新时,至少有2个需要更新的对象(或1个需要重新计算)。但如果我采用这种方法,第二个问题有什么想法吗? –

+0

我在回答中添加了更多内容以开始解决删除线问题。至于为什么打扰一个视图模型?查看模型并不总是必需的,但是您的项目变得越大,在数据库中需要存储的内容和需要存储在屏幕上的内容之间建立一个硬性分隔就越有帮助。阅读MVVM模式将有助于使这一点更加清晰。 – devuxer

0

您可以修改类为如下所示:

public class TimeStamp 
    { 
     private string _HourList; 
     private string _DayList; 
     private string[] _DaysOfWeek; 
     private string[] _HoursOfDay; 
     public string[] HoursOfDay 
     { 
      get { return _HoursOfDay; } 
      set 
      { 
       _HoursOfDay = value; 
       _HourList = String.Join("|", value); 
      } 
     } 
     public int ID { get; set; } 
     public string[] DaysOfWeek 
     { 
      get { return _DaysOfWeek; } 
      set 
      { 
       _DaysOfWeek = value; 
       _DayList = String.Join("|", value); 
      } 
     } 
     public string DayLis 
     { 
      get { return _DayList; } 
     } 
     public string HourList 
     { 
      get { return _HourList; } 
     } 
    } 

定义这样的类的优点:

每当你将值分配给字符串数组DaysOfWeek它将 在于所有数组元素 洁具用分隔符组合在一起自动创建字符串,由于DayList是只读 属性,您不能为其分配值。你会从这个属性获得的价值 以及在结合

因此您xamal加价的时间将是这样的:

<StackPanel Orientation="Vertical" VerticalAlignment="Center"> 
     <TextBlock Text="{Binding ID}"/> 
     <TextBlock Text="{Binding DayLis}"/> 
</StackPanel> 
0

你想作为一个TextBlock文本显示DaysOfWeek 。 DaysOfWeek是一个字符串数组,不是一个字符串,所以它不会像预期的那样显示。您必须转换为字符串,并且可以在转换函数中指定格式。你必须种方法将字符串数组转换为格式化字符串中WPF

首先解决:本更好的,但复杂的方式

public class WeekDaysFormatConverter : System.Windows.Data.IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if(value != null && value is string[]) 
     { 
      return string.Join("|", value as string[]); 
     } 

     return value; 
    } 

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

,并将其应用:

<Window.Resources> 
    <local:WeekDaysFormatConverter x:Key="WeekDaysFormatConverter" /> 
</Window.Resources> 
... 
<TextBlock Text="{Binding DaysOfWeek Converter={StaticResource WeekDaysFormatConverter}}"/> 

第二类解决方案:只需使用属性来指定格式:

public class TimeStamp 
{ 
    public int ID { get; set; } 
    public string[] DaysOfWeek { get; set; } 
    public string[] HoursOfDay { get; set; } 

public string DaysOfWeekFormatted 
    { 
     get 
     { 
      return DaysOfWeek != null ? string.Join("|", DaysOfWeek) : string.Empty; 
     } 
    } 
} 

,并将其应用:

<TextBlock Text="{Binding DaysOfWeekFormatted}"/> 
相关问题