2012-05-09 4 views
0

私は、ViewModelsに入れられたTFSビルドに関するサービスから収集された情報を持っています。ここ はモデルです:WPF Datagrid階層データを文字列として記録

public class Collection : ViewModel 
{ 
    private string _name = string.Empty; 

    public string Name 
    { 
     get { return _name; } 
     set 
     { 
      _name = value; 
      OnPropertyChanged(() => Name); 
     } 
    } 

    private ObservableCollection<Project> _projects = new ObservableCollection<TFSProject>(); 

    public ObservableCollection<Project> Projects 
    { 
     get { return _projects; } 
     set 
     { 
      _projects = value; 
      OnPropertyChanged(() => Projects); 
     } 
    } 

} 

public class Project : ViewModel 
{ 
    private string _name = string.Empty; 

    public string Name 
    { 
     get { return _name; } 
     set 
     { 
      _name = value; 
      OnPropertyChanged(() => Name); 
     } 
    } 

    private ObservableCollection<string> _buildDefinitions = new ObservableCollection<string>(); 

    public ObservableCollection<string> BuildDefinitions 
    { 
     get { return _buildDefinitions; } 
     set 
     { 
      _buildDefinitions = value; 
      OnPropertyChanged(() => BuildDefinitions); 
     } 
    } 
} 

私はObservableCollection<Collection>に私のコンボボックスののItemsSourceを結合しています。私のXAMLで

public class BuildMonitor : INotifyPropertyChanged 
{ 
    [Description("In TFS, each team project exists within a TFS Collection. This is the name of the collection applicable to the build that this monitor is for. Default='Vision2010'")] 
    public string Collection 
    { 
     get { return collection_; } 
     set 
     { 
      collection_ = value; 
      OnPropertyChanged(() => Collection); 
     } 
    } 
    private string collection_ = "Vision2010"; 

    [Description("BuildDefintions reside within a TeamProject. This is the name of the TeamProject where the build definition this monitor is for resides. Default='Double-Take2010'")] 
    public string TeamProject { get { return teamProject_; } set { teamProject_ = value; OnPropertyChanged(() => TeamProject); } } 
    private string teamProject_ = "Double-Take2010"; 

    [Description("Builds are defined in TFS as the execution of a particular BuildDefinition. This is the name of the build defintion (thus; the build) this monitor is for.")] 
    public string BuildDefinition { get { return buildDefinition_; } set { buildDefinition_ = value; OnPropertyChanged(() => BuildDefinition); } } 
    private string buildDefinition_; 

    [Description("Used only if this monitor should watch for builds specified by a particular user. Enter the domain name of the user, or leave blank to monitor builds by any user.")] 
    public string RequestedByFilter { get { return requestedByFilter_; } set { requestedByFilter_ = value; OnPropertyChanged(() => RequestedByFilter); } } 
    private string requestedByFilter_; 

    [Description("The command to execute when the build monitor is triggered.")] 
    public string Command { get { return command_; } set { command_ = value; OnPropertyChanged(() => Command); } } 
    private string command_; 

    [Description("The arguments to pass to the command. Arguments will resolve known build monitor macros.")] 
    public string Arguments { get { return arguments_; } set { arguments_ = value; OnPropertyChanged(() => Arguments); } } 
    private string arguments_; 

    [Description("If TRUE, the monitor will fire only once, at which point it will be marked as 'invalid' and never fire again.")] 
    public bool RunOnce { get { return runOnce_; } set { runOnce_ = value; OnPropertyChanged(() => RunOnce); } } 
    private bool runOnce_ = false; 

    [Description("The maximum age (in hours) a build can be (since finished), for the monitor to consider it for processing. Default='0'")] 
    public int MaxAgeInHours { get { return maxAgeInHours_; } set { maxAgeInHours_ = value; OnPropertyChanged(() => MaxAgeInHours); } } 
    private int maxAgeInHours_ = 0; 

    [Description("Which status trigger the monitor should 'fire' on. When the build status matches this trigger, the monitor command will be executed. Default='Succeeded'")] 
    public BuildStatus EventTrigger { get { return eventTrigger_; } set { eventTrigger_ = value; OnPropertyChanged(() => EventTrigger); } } 
    private BuildStatus eventTrigger_ = BuildStatus.Succeeded; 

    [Browsable(false), Description("Used internally to reliably compare two BuildMonitors against each other.")] 
    public Guid ID { get { return id_; } set { id_ = value; } } 
    private Guid id_ = Guid.NewGuid(); 

    [Browsable(false), Description("Used internally to determine if the monitor is still valid/should be processed.")] 
    public bool IsEnabled { get { return isEnabled_; } set { isEnabled_ = value; } } 
    private bool isEnabled_ = true; 

    [Browsable(false), XmlIgnore, Description("Used internally to track when the monitor is 'busy' (currently running the 'Command' selected.")] 
    public int CurrentProcessID { get { return currentProcessID_; } set { currentProcessID_ = value; } } 
    private int currentProcessID_ = 0; 

    [Browsable(false), XmlIgnore, Description("Used internally to track the build that the monitor is currently processing.")] 
    private string currentBuildUri_; 
    public string CurrentBuildUri { get { return currentBuildUri_; } set { currentBuildUri_ = value; } } 

    [field: NonSerialized, Browsable(false)] 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged<T>(Expression<Func<T>> propertyExpression) 
    { 
     MemberExpression memberExpression = (MemberExpression)propertyExpression.Body; 
     string propertyName = memberExpression.Member.Name; 

     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

私は、このデータの選択を表すことを試みてきたのItemsSourceを設定することによって:問題は、コレクション、プロジェクト、およびビルド定義名が別の文字列プロパティとしてそれらを定義するクラスに格納されていることですコレクションコンボボックスの相対的なソースバインディング(ObservableCollection<Collection>)に移動します。私はリストの項目をOKにしますが、itemssourceはList<BuildMonitors>なので、選択した項目の名前プロパティをデータ項目の実際のバインディングにマッピングするようには見えません(BuildMonitorのString Collectionインスタンス)。

<tk:DataGrid ItemsSource="{Binding Monitors}" 
       AutoGenerateColumns="False"> 
<tk:DataGrid.Columns>  
    <tk:DataGridTemplateColumn Header="Collection"> 
     <tk:DataGridTemplateColumn.CellEditingTemplate> 
      <DataTemplate> 
       <ComboBox x:Name="Collection" 
           ItemsSource="{Binding Path=AllCollections, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type apollo:BuildMonitorNew}}}" 
           DisplayMemberPath="Name" 
           SelectedItem="{Binding .}" 
           SelectedValuePath="Collection" 
           SelectedValue="{Binding Name}"/> 
      </DataTemplate> 
     </tk:DataGridTemplateColumn.CellEditingTemplate> 
     <tk:DataGridTemplateColumn.CellTemplate> 
      <DataTemplate> 
       <TextBlock Text="{Binding Collection,Mode=TwoWay}"/> 
      </DataTemplate> 
     </tk:DataGridTemplateColumn.CellTemplate> 
    </tk:DataGridTemplateColumn> 
    <tk:DataGridTemplateColumn Header="Project"> 
     <tk:DataGridTemplateColumn.CellEditingTemplate> 
      <HierarchicalDataTemplate ItemsSource="{Binding ElementName=Collection,Path=SelectedItem.Projects}"> 
       <ComboBox x:Name="Projects" 
           ItemsSource="{Binding}" 
           DisplayMemberPath="Name"/> 
      </HierarchicalDataTemplate> 
     </tk:DataGridTemplateColumn.CellEditingTemplate> 
    </tk:DataGridTemplateColumn> 
    <tk:DataGridTextColumn Binding="{Binding Command}" 
            Header="Command"/> 
    <tk:DataGridTextColumn Binding="{Binding Arguments}" 
            Header="Arguments" 
            Width="*"/> 
</tk:DataGrid.Columns> 

私が最初に考えたのは私のviewmodelを(階層)のデータをより良く表現かもしれないが、実店舗へのデータ対を選択するためのデータの構造があまりにも異なっていることです。

実際に選択されたデータ(コレクション、プロジェクト、およびBuildDefinition)を、格納されているデータ(BuildMonitor)のパスに変換するうれしい方法を見つけたいと思います。

アイデア?

+0

が私のために問題に答え。私は私の解決策を投稿する – Csharpfunbag

答えて

0

多値変換器では、リストを表すコンボボックスアイテムソースの階層構造をパートに変換することができました。

コンバータ:

public class BuildMonitorItemSource : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (values.Count() == 2) 
     { 
      string collectionToGet = parameter.ToString(); 

      ObservableCollection<TFSCollection> allcollections = values[1] as ObservableCollection<TFSCollection>; 

      BuildLauncher.BuildMonitor currentBM = (values[0] as BuildLauncher.BuildMonitor); 

      if (collectionToGet.Equals("Projects")) 
      { 
       return allcollections.FirstOrDefault(x => x.Name.Equals(currentBM.Collection, StringComparison.OrdinalIgnoreCase)).Projects; 

      } 
      else if (collectionToGet.Equals("BuildDefinitions")) 
      { 
       TFSCollection currentCollection = allcollections.FirstOrDefault(x => x.Name.Equals(currentBM.Collection)); 

       TFSProject currentProject = currentCollection.Projects.FirstOrDefault(x => x.Name.Equals(currentBM.TeamProject)); 

       return currentProject.BuildDefinitions; 
      } 
     } 
     return values; 
    } 

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

これが変更されたXMLです:私は多値コンバータを使用してい

<tk:DataGrid ItemsSource="{Binding Monitors}" 
           AutoGenerateColumns="False" 
           IsEnabled="{Binding RelativeSource={RelativeSource AncestorType=apollo:BuildMonitorNew}, Path=TFSAuthenticated}" 
           Name="MontiorsGrid"> 
        <tk:DataGrid.Columns> 
         <tk:DataGridCheckBoxColumn Binding="{Binding IsEnabled}"> 
          <tk:DataGridCheckBoxColumn.Header> 
           <Ellipse Grid.Column="0" 
                  HorizontalAlignment="Left" 
                  Height="10" Width="10"                
                  Stroke="Black" 
                  StrokeThickness="1" 
                  Fill="Green"/> 
          </tk:DataGridCheckBoxColumn.Header> 
         </tk:DataGridCheckBoxColumn> 
         <tk:DataGridTemplateColumn Header="Collection"> 
          <tk:DataGridTemplateColumn.CellEditingTemplate> 
           <DataTemplate> 
            <ComboBox x:Name="CollectionCombo" 
               ItemsSource="{Binding Path=AllCollections, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type apollo:BuildMonitorNew}}}" 
               DisplayMemberPath="Name" 
               SelectedValue="{Binding Collection}" 
               SelectedValuePath="Name"> 
            </ComboBox> 
           </DataTemplate> 
          </tk:DataGridTemplateColumn.CellEditingTemplate> 
          <tk:DataGridTemplateColumn.CellTemplate> 
           <DataTemplate> 
            <TextBlock Text="{Binding Collection,Mode=TwoWay}"/> 
           </DataTemplate> 
          </tk:DataGridTemplateColumn.CellTemplate> 
         </tk:DataGridTemplateColumn> 
         <tk:DataGridTemplateColumn Header="Project"> 
          <tk:DataGridTemplateColumn.CellEditingTemplate> 
           <DataTemplate> 
            <ComboBox x:Name="Projects" 
               DisplayMemberPath="Name" 
               SelectedValue="{Binding TeamProject}" 
               SelectedValuePath="Name"> 
             <ComboBox.ItemsSource> 
              <MultiBinding Converter="{StaticResource GetItemSource}" ConverterParameter="Projects" > 
               <Binding Path="." /> 
               <Binding Path="AllCollections" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType={x:Type apollo:BuildMonitorNew}}"/> 
              </MultiBinding> 
             </ComboBox.ItemsSource> 
            </ComboBox> 
           </DataTemplate> 
          </tk:DataGridTemplateColumn.CellEditingTemplate> 
          <tk:DataGridTemplateColumn.CellTemplate> 
           <DataTemplate> 
            <TextBlock Text="{Binding TeamProject,Mode=TwoWay}"/> 
           </DataTemplate> 
          </tk:DataGridTemplateColumn.CellTemplate> 
         </tk:DataGridTemplateColumn> 
         <tk:DataGridTemplateColumn Header="Build Definition"> 
          <tk:DataGridTemplateColumn.CellEditingTemplate> 
           <DataTemplate> 
            <ComboBox SelectedItem="{Binding BuildDefinition}"> 
             <ComboBox.ItemsSource> 
              <MultiBinding Converter="{StaticResource GetItemSource}" ConverterParameter="BuildDefinitions"> 
               <Binding Path="." /> 
               <Binding Path="AllCollections" RelativeSource="{RelativeSource Mode=FindAncestor,AncestorType={x:Type apollo:BuildMonitorNew}}"/> 
              </MultiBinding> 
             </ComboBox.ItemsSource> 
            </ComboBox> 
           </DataTemplate> 
          </tk:DataGridTemplateColumn.CellEditingTemplate> 
          <tk:DataGridTemplateColumn.CellTemplate> 
           <DataTemplate> 
            <TextBlock Text="{Binding BuildDefinition,Mode=TwoWay}"/> 
           </DataTemplate> 
          </tk:DataGridTemplateColumn.CellTemplate> 
         </tk:DataGridTemplateColumn> 
         <tk:DataGridTextColumn Binding="{Binding Command}" 
                 Header="Command"/> 
         <tk:DataGridTextColumn Binding="{Binding Arguments}" 
                 Header="Arguments" 
                 Width="*"/> 
        </tk:DataGrid.Columns> 
       </tk:DataGrid> 
関連する問題