2012-12-06 4 views
2

또한 at Infragistics이라고 물었습니다. 그러나 여기에 내 코드의 서식을 지정하는 방법을 모르므로 여기에 서식이 올바르게 지정되어 있습니다.cellValuePresenter/TypeConverter를 XamDataGrid 셀에 적용 할 수 없습니다.

내 목표는 여러 색상을 사용하여 각 셀의 텍스트로 구조화 된 데이터의 테이블을 제공하는 것입니다. 맞춤형 클래스에 저장된 데이터를 여러 색상으로 된 여러 텍스트 요소가 포함 된 레이블 또는 텍스트 블록으로 변환하는 typeconverter가 있습니다. 데이터는 데이터 테이블 (작동하는 모든 메소드)에 제공되며 각 값은 셀에 올바르게 적용됩니다.

문제는 내 TypeConverter를 사용하는 대신 ToString 메서드를 사용하는데,이 모델은 모델 데이터가 셀별로 그리드 셀에 매핑된다는 것을 알기 때문에 재정의합니다. 또한 내가 사용하고있는 ControlTemplate 속성이 적용되지 않아 ControlTemplate이 사용되지 않는다고 알려줍니다.

DataGrid에서 다른 글자의 색상이 다른 곳에 텍스트를 배치 할 수 없다는 우려가 있습니다. 그렇다면 좋은 사용자 환경을 유지하면서 xaml 파일 (그리드가 딱딱한)에 디자인을 유지하면서 다른 방법을 사용할 수 있습니까?

내 코드는 사용자 정의 CellValuePresenter를 정의해야합니다. 아무도 나를 적용 해 주시겠습니까?

여기에 관련 코드를 게시합니다. 대부분은 난독 화되어 있으므로 철자 오류에 집중하지 마십시오.

<Window x:Class="ViewName" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:local="clr-namespace:LocalNamespace" 
      xmlns:ViewModel="clr-namespace:LocalNamespace.ViewModel" 
      xmlns:model="clr-namespace:LocalNamespace.Model" 
      xmlns:igDP="http://infragistics.com/DataPresenter" 
      > 
     <Window.Resources> 
      <local:Converter x:Key="converter" /> 
      <ViewModel:ViewModelLocator x:Key="viewModelLocator" /> 
      <Style TargetType="{x:Type igDP:CellValuePresenter}" x:Key="cellTemplate" x:Name="cellTemplate" > 
       <Setter Property="Template"> 
        <Setter.Value> 
         <ControlTemplate TargetType="{x:Type igDP:CellValuePresenter}"> 
          <Label 
           Content="{Binding Converter={StaticResource converter}}" 
           Width="200" 
           MaxWidth="600" 
           MinHeight="20" 
           /> 
         </ControlTemplate> 
        </Setter.Value> 
       </Setter> 
      </Style> 
     </Window.Resources> 
     <StackPanel Name="stackPanel"> 
      <igDP:XamDataGrid Name="DifferenceGrid" DataSource="{Binding Source={StaticResource viewModelLocator}, Path=ViewModel.Model}" 
           ScrollViewer.CanContentScroll="True" ScrollViewer.HorizontalScrollBarVisibility="Visible" ScrollViewer.VerticalScrollBarVisibility="Visible"> 
       <igDP:XamDataGrid.FieldLayouts> 
        <igDP:FieldLayout> 
         <igDP:FieldLayout.Fields> 
          <igDP:Field> 
           <igDP:Field.Settings> 
            <igDP:FieldSettings 
             CellValuePresenterStyle="{StaticResource cellTemplate}"> 
            </igDP:FieldSettings> 
           </igDP:Field.Settings> 
          </igDP:Field> 
         </igDP:FieldLayout.Fields> 
        </igDP:FieldLayout> 
       </igDP:XamDataGrid.FieldLayouts> 
      </igDP:XamDataGrid> 
     </StackPanel> 
    </Window> 

    class ViewModelLocator 
    { 
     private static ViewModel viewModel = new ViewModel(); 

     public ViewModel ViewModel 
     { 
      get 
      { 
       return viewModel; 
      } 
     } 
    } 

    public class ViewModel 
    { 
     private DataTable model; 

     public DataTable Model 
     { 
      get 
      { 
       return this.model; 
      } 

      private set 
      { 
       this.model = value; 
      } 
     } 

    [global::System.ComponentModel.TypeConverter(typeof(Model.CustomClass))] 
    public class Converter : TypeConverter, IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      if (this.CanConvertTo(targetType)) 
      { 
       return this.ConvertTo(value); 
      } 
      else 
      { 
       return null; 
      } 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
     { 
      if (this.CanConvertFrom(targetType)) 
      { 
       return this.ConvertFrom(value); 
      } 
      else 
      { 
       return null; 
      } 
     } 

     public new bool CanConvertFrom(Type sourceType) 
     { 
      // Textboxes don't need to be converted back. 
      return sourceType == typeof(Model.CustomClass); 
     } 

     public new bool CanConvertTo(Type destinationType) 
     { 
      return destinationType == typeof(Model.CustomClass); 
     } 

     public object ConvertTo(object value) 
     { 
      return this.ConvertCustomClassToTextBlock(value); 
     } 

     public new object ConvertFrom(object value) 
     { 
      return this.ConvertCustomClassToTextBlock(value); 
     } 

     private object ConvertCustomClassToTextBlock(object value) 
     { 
      TextBlock text = new TextBlock(); 
      Label cell = new Label(); 

     // Construct the TextBlock. 

     cell.Context = text; 
     return text; // Or cell, whatever works. 
    } 
    } 

답변

4

XamDataGrid 셀에는 편집기가 포함되어 있으며 텍스트로 표시되어야하는 값의 경우 편집기는 XamTextEditor입니다.

당신은 XamTextEditor의 템플릿을 수정하고 다음 코드처럼 자신의를 제공해야해야

using System; 
using System.Collections.Generic; 
using System.Globalization; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Media; 
using Infragistics.Windows.DataPresenter; 
using Infragistics.Windows.Editors; 

namespace XamDataGridApp 
{ 
    class XamTextEditorConverter : IMultiValueConverter 
    { 
     private static readonly IList<Brush> colors = new Brush[] { Brushes.Red, Brushes.Green, Brushes.Blue }; 

     public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
     { 
      var displayText = (string)values[0] ?? string.Empty; 

      // Context that can be used for custom coloring. 
      var editor = (XamTextEditor)values[1]; 
      var dataItemPresenter = editor.Host as DataItemPresenter; 

      // Context that can be used for custom coloring. 
      var dataValue = editor.Value; 
      var dataItem = dataItemPresenter != null ? dataItemPresenter.Record.DataItem : null; 

      var textBlock = new TextBlock() 
      { 
       TextWrapping = editor.TextWrapping, 
       TextAlignment = editor.TextAlignment 
      }; 

      for (int i = 0; i < displayText.Length; ++i) 
       textBlock.Inlines.Add(new Run(displayText[i].ToString()) { Foreground = colors[i % colors.Count] }); 

      return textBlock; 
     } 

     public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
     { 
      throw new NotSupportedException(); 
     } 
    } 
} 

ContentPresenter에 XamTextEditor 템플릿 내부 :

<Window x:Class="XamDataGridApp.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:igDP="http://infragistics.com/DataPresenter" 
     xmlns:igEditors="http://infragistics.com/Editors" 
     xmlns:local="clr-namespace:XamDataGridApp" 
     Title="Colorful XamDataGrid" SizeToContent="WidthAndHeight"> 
    <igDP:XamDataGrid FieldLayoutInitialized="OnFieldLayoutInitialized"> 
     <igDP:XamDataGrid.DataSource> 
      <!-- Replace this with your data source. --> 
      <local:DataSourceMock/> 
     </igDP:XamDataGrid.DataSource> 
     <igDP:XamDataGrid.Resources> 
      <local:XamTextEditorConverter x:Key="XamTextEditorConverter" x:Shared="True"/> 
      <Style TargetType="igEditors:XamTextEditor" BasedOn="{StaticResource {x:Type igEditors:XamTextEditor}}"> 
       <Style.Setters> 
        <Setter Property="Template"> 
         <Setter.Value> 
          <ControlTemplate TargetType="{x:Type igEditors:XamTextEditor}"> 
           <Border x:Name="MainBorder" 
             Background="{TemplateBinding Background}" 
             BorderBrush="{TemplateBinding BorderBrush}" 
             BorderThickness="{TemplateBinding BorderThickness}" 
             SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"> 
            <ContentPresenter 
             Margin="{TemplateBinding Padding}" 
             HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
             VerticalAlignment="{TemplateBinding VerticalContentAlignment}"> 
             <ContentPresenter.Content> 
              <MultiBinding Converter="{StaticResource XamTextEditorConverter}"> 
               <Binding Path="DisplayText" RelativeSource="{RelativeSource TemplatedParent}"/> 
               <Binding RelativeSource="{RelativeSource TemplatedParent}"/> 
              </MultiBinding> 
             </ContentPresenter.Content> 
            </ContentPresenter> 
           </Border> 
          </ControlTemplate> 
         </Setter.Value> 
        </Setter> 
       </Style.Setters> 
      </Style> 
      <Style TargetType="igEditors:XamTextEditor" x:Key="CustomClassXamTextEditorStyle" x:Shared="True" BasedOn="{StaticResource {x:Type igEditors:XamTextEditor}}"> 
       <Setter Property="ValueToDisplayTextConverter" Value="{x:Static local:CustomClassToStringConverter.Instance}"/> 
       <Setter Property="ValueToTextConverter" Value="{x:Static local:CustomClassToStringConverter.Instance}"/> 
      </Style> 
     </igDP:XamDataGrid.Resources> 
    </igDP:XamDataGrid> 
</Window> 

다음 IMultiValueConverter는 명령 적 XamTextEditor 컨텐츠를 생성하는 데 사용됩니다 XamDataGrid 셀이 가상화되고 바인딩을 사용하여 셀 가상화가 시작될 때 ContentPresenter 내용을 다시 생성하도록 XamDataGrid에 지시하는 경우 (CellValueP 재주 인이 다른 값을 제시하기 위해 재사용 됨). 또한 데이터 바인딩으로 인해 XamDataGrid 외부에서 내용이 변경 되더라도 내용이 다시 생성됩니다.

MultiBinding은 데이터 값과 데이터 항목을 추출하고 채색 논리에서 사용할 수있는 컨텍스트 (XamTextEditor)를 전달하는 데 사용됩니다. 컨텍스트가 필요하지 않은 경우 IValueConverter를 사용하는 DisplayText에 대한 간단한 바인딩을 대신 사용할 수 있습니다.


UPDATE : 위해

당신의 컨버터 XamDataGrid 사용할 수 있도록하기위한 다음과 같은 XAML 조각처럼 FieldSettings에서 CellValuePresenterStyle (안 FieldLayouts)를 정의해야합니다

<igDP:XamDataGrid Name="DifferenceGrid" DataSource="{Binding Source={StaticResource viewModelLocator}, Path=ViewModel.Model}" 
         ScrollViewer.CanContentScroll="True" ScrollViewer.HorizontalScrollBarVisibility="Visible" ScrollViewer.VerticalScrollBarVisibility="Visible"> 
    <igDP:XamDataGrid.FieldSettings> 
     <igDP:FieldSettings CellValuePresenterStyle="{StaticResource cellTemplate}"/> 
    </igDP:XamDataGrid.FieldSettings> 
</igDP:XamDataGrid> 

을 이 코드 스 니펫을 사용하면 XamDataGrid의 모든 셀에 대해 기본 CellValuePresenterStyle을 지정할 수 있습니다.

당신은 당신의에서는 CustomClass 열 XamTextEditor를 사용하고 다른 모든 열은 자신의 기본 편집기를 사용하면 다음 코드에서와 같이 FieldLayoutInitialized 이벤트를 처리하여 작업을 수행 할 수 있음을 지정하려면 :

private void OnFieldLayoutInitialized(object sender, FieldLayoutInitializedEventArgs e) 
{ 
    foreach (var field in e.FieldLayout.Fields) 
     if (field.DataType == typeof(Model.CustomClass)) 
     { 
      field.Settings.EditorType = typeof(XamTextEditor); 
      // Set Editor style in which display converter and edit converter are specified. 
      field.Settings.EditorStyle = (Style)((FrameworkElement)sender).FindResource("CustomClassXamTextEditorStyle"); 
     } 
} 

MainWindow.xaml 이 변경 사항을 반영하도록 위에서 업데이트되었습니다.

다음은 CustomClass를 문자열로 변환하고 다시 XamDataGrid에서 CustomClass를 편집하고 편집 할 때 사용했던 CustomClassToStringConverter 코드입니다 (사용자가 텍스트를 추출하는 방법을 모르기 때문에 CustomClass에 Text 속성을 추가했습니다) :

class CustomClassToStringConverter : IValueConverter 
{ 
    public static CustomClassToStringConverter Instance = new CustomClassToStringConverter(); 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return ((CustomClass)value).Text; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return new CustomClass() { Text = (string)value }; 
    } 
} 
+0

감사합니다. 이것은 적어도 원칙적으로 가능함을 보여줍니다. 나는 당신의 모범을 얻었으니, 이제는 내 창에서 그것을 구현하려고한다. 내 창에서 XamTextEditor는 적용되지 않습니다. 다른 템플리트가 적용되지 않는 것과 거의 같은 문제입니다. – MrFox

+0

내 typeconverter를 호출 할 수 없습니다. – MrFox

+0

업데이트 된 답변보기 – Stipo

0

덕분에 지금은 작업을 얻었다. 별도의 데이터 소스에 텍스트 블록을 제공해야 했으므로 이제는 멀티 바인딩이 필요하지 않습니다. 그러나 MVVM이 여전히 적용되는지는 잘 모르겠지만 꽤 못생긴 해결책입니다.

public DataTable TextBlocks 
    { 
     get 
     { 
      Converter converter = new DifferenceToTextConverter(); 
      DataTable table = new DataTable(); 

      foreach (DataColumn col in this.Model.Columns) 
       table.Columns.Add(col.ColumnName, typeof(TextBlock)); 

      foreach (DataRow row in this.Model.Rows) 
      { 
       DataRow addedRow = table.NewRow(); 
       for (int col = 0; col < row.ItemArray.Length; col++) 
       { 
        addedRow[col] = converter.ConvertTo(row[col]); 
       } 

       table.Rows.Add(addedRow); 
      } 

      return table; 
     } 
    } 
관련 문제