2012-05-24 45 views
0

我需要將我的ObservableCollection<ValidationMessage>放入我的TextBlock。這是我的代碼。現在它顯示Item和SubItems,但消息顯示它有System.Collections.ObjectModel.ObservableCollection'1[ValidationWPF.DataSources.‌​ValidationMessages]如何將ObservableCollection放入文本塊

我認爲這是因爲它不能把ObservableCollection放入TextBlock

XAML:

<UserControl x:Class="ValidationWPF.ValidationUserControl" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" 
      xmlns:local="clr-namespace:ValidationWPF.DataSources" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <UserControl.Resources> 
     <DataTemplate x:Key="Messages"> 
      <TextBlock Text="{Binding Message}"/> 
     </DataTemplate> 



    </UserControl.Resources> 
    <Grid x:Name="LayoutRoot" Background="White"> 

     <telerik:RadTreeView x:Name="radTreeView" Margin="8"> 
      <telerik:RadTreeView.ItemTemplate> 



       <HierarchicalDataTemplate ItemsSource="{Binding SubItems}"> 
        <TextBlock Text="{Binding item}" /> 
       </HierarchicalDataTemplate> 

      </telerik:RadTreeView.ItemTemplate> 
     </telerik:RadTreeView> 

    </Grid> 
</UserControl> 

ValidationMessage類:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace ValidationWPF.DataSources 
{ 
    public class ValidationMessage 
    { 
     public ValidationMessage(string Message) 
     { 
      this.Message = Message; 
     } 

     public string Message 
     { 
      get; 
      set; 
     } 

    } 
} 

ValidationItem類:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Collections.ObjectModel; 

namespace ValidationWPF.DataSources 
{ 
    public class ValidationItem : ObservableCollection<ValidationItem> 
    { 
     public ValidationItem() 
     { 
      SubItems = new ObservableCollection<ValidationItem>(); 


     } 


     public ObservableCollection<ValidationMessage> Message 
     { 
      get; 
      set; 
     } 

     public string item 
     { 
      get; 
      set; 
     } 

     public IList<ValidationItem> SubItems 
     { 
      get; 
      set; 
     } 

     public static IList<ValidationItem> GetItems(string name) 
     { 
      var Validation = new ObservableCollection<ValidationItem>(); 


      var item = new ValidationItem(); 
      item.item = "Customer"; 


      var subItem = new ValidationItem(); 
      subItem.item = "Name"; 
      item.SubItems.Add(subItem); 

      var Message = new ValidationItem(); 
      Message.item = new ObservableCollection<ValidationMessage>().ToString(); 
      subItem.SubItems.Add(Message); 






      Validation.Add(item); 

      return Validation; 

     } 
    } 
} 

謝謝您的幫助!

回答

2

我最終以一種不同的,更清潔的方式做到了這一點。

XAML:

<UserControl x:Class="ValidationWPF.ValidationUserControl" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" 
      xmlns:local="clr-namespace:ValidationWPF.DataSources" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <UserControl.Resources> 
     <!--<local:CollectionConverter x:Key="CollectionConverter"/> 
      <DataTemplate x:Key="Messages"> 
      <TextBlock Text="{Binding Message}"/> 
     </DataTemplate>--> 




    </UserControl.Resources> 
    <Grid x:Name="LayoutRoot" Background="White"> 

     <telerik:RadTreeView x:Name="radTreeView" Margin="8" ItemsSource="{Binding Errors}"> 
      <telerik:RadTreeView.ItemTemplate> 
       <HierarchicalDataTemplate ItemsSource="{Binding SubItems}" > 
        <Grid> 
         <Grid.RowDefinitions> 
          <RowDefinition/> 
          <RowDefinition/> 
         </Grid.RowDefinitions> 
         <TextBlock Text="{Binding Description}"/> 

         <ListBox Grid.Row="1" ItemsSource="{Binding Messages}"> 
          <ListBox.ItemTemplate> 
           <DataTemplate> 
            <TextBlock Text="{Binding Message}"/> 
           </DataTemplate> 
          </ListBox.ItemTemplate> 
         </ListBox> 
        </Grid> 

       </HierarchicalDataTemplate> 

      </telerik:RadTreeView.ItemTemplate> 
     </telerik:RadTreeView> 

    </Grid> 
</UserControl> 

VALIDATIONMESSAGE類:

using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 

    namespace ValidationWPF.DataSources 
    { 
     public class ValidationMessage 
     { 
      public ValidationMessage(string name, string Message) 
      { 
       this.Message = Message; 
       this.PropertyName = name; 
      } 

      public string Message 
      { 
       get; 
       set; 
      } 

      public string PropertyName { get; set; } 

     } 
    } 

VALIDATIONVIEWMODEL CLASS: 

    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using System.Collections.ObjectModel; 

    namespace ValidationWPF.DataSources 
    { 
     public class ValidationViewModel 
     { 
      public ValidationViewModel() 
      { 
       this.Errors = new ObservableCollection<ValidationItem>(); 

       ValidationItem item = new ValidationItem(); 
       item.Description = "Customer"; 

       ValidationMessage msg = new ValidationMessage("FirstName", "First name is required"); 
       item.Messages.Add(msg); 


       this.Errors.Add(item); 

       ValidationItem item2 = new ValidationItem(); 
       item2.Description = "Order"; 

       msg = new ValidationMessage("Quantity", "Quantity must be greater than zero"); 
       item2.Messages.Add(msg); 


       item.SubItems.Add(item2); 

      } 

      public ObservableCollection<ValidationItem> Errors { get; set; } 
     } 
    } 

VALIDATIONUSERCONTROL類:

public partial class ValidationUserControl : UserControl 
    { 
     public ValidationUserControl() 
     { 
      InitializeComponent(); 
      this.DataContext = new ValidationViewModel(); 

     } 

    } 
2

你說得對。 TextBlock嘗試以String的形式查看屬性值,並且ObservableCollection.ToString將只返回您所看到的內容。

您可以做的是添加一個新的屬性,將ObservableCollection的所有消息合併到一個字符串中。例如:

public string MessagesCombined 
{ 
    get { return string.Join(Environment.NewLine, Message.Select(m => m.Message)); } 
} 

這會將ObservableCollection中的所有消息合併到一個字符串中,每個項目用換行符分隔。 (你可能需要修改我的代碼,我正在編寫這個程序,不能訪問編譯器......)。

+0

這看起來像它可以工作。然後我怎麼能實現這個到我的hierarchicaldatatemplate使它顯示像客戶名稱消息(這應該像父母,孩子,孫子) – JLott

3

問題是TextBlockText屬性是一個字符串,並且您給它一個ObservableCollection。 WPF知道轉換兩者的唯一方法是調用ObservableCollection.ToString(),它返回類的完整類型名稱。

解決的辦法是通過創建一個實現System.Windows.Data.IValueConverter的類來將ObservableCollection轉換爲字符串。這使您可以控制轉換。

你可以實現它是這樣的:

using System.Globalization; 
using System.Text; 
using System.Windows.Data; 

namespace ValidationWPF.DataSources 
{ 
    class CollectionConverter : IValueConverter 
    { 
     object Convert(object value, Type targetType,object parameter,CultureInfo culture) 
     { 
      ObservableCollection<ValidationMessage> messages = (ObservableCollection<ValidationMessage>)value; 

      var sb = new StringBuilder(); 
      foreach(var msg in messages) 
      { 
       sb.AppendLine(msg.Message); 
      } 

      return sb.ToString(); 
     } 

     object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      return null; 
     } 
    } 
} 

而且你可以在你的XAML文件中使用這樣的:

<UserControl x:Class="ValidationWPF.ValidationUserControl" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" 
      xmlns:local="clr-namespace:ValidationWPF.DataSources" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <UserControl.Resources> 
     <local:CollectionConverter x:Key="CollectionConverter" /> 

     <DataTemplate x:Key="Messages"> 
      <TextBlock Text="{Binding Message, Converter={StaticResource CollectionConverter}}"/> 
     </DataTemplate> 
    </UserControl.Resources> 
    ... 
</UserControl> 

現在WPF將調用CollectionConverter.Convert()每當需要填充您TextBlock

+0

好!我需要我的消息顯示在我的HierarchicalDataTemplate中,儘管...應該是Customers,Name,不能以Parent,Child,GrandParent的順序爲空。 – JLott

+0

@JLott這取決於物品的類型。你也許可以做類似的事情,併爲此創建一個價值轉換器。 – Andy

+0

其餘的項目只是鍵入字符串。我只需要轉換那一個。現在我無法將其綁定到DataTemplate,如上面的代碼所示。 – JLott