Question

all. I have an XamDataGrid of objects; each object has two properties I want to edit within the grid. I'm creating my FieldLayout programatically, to allow a varying number of columns. When I define my layout, I can set the binding for each Field so the PropertyPath points to a particular column in my ViewModel ((i.e. Path="Columns[0]", Path="Columns[1]", etc.) This works fine:

http://imgur.com/rJLCKiR

I want to apply a template to the CellValuePresenter to let me edit each field, with one textbox bound to each of the two fields:

http://imgur.com/9IEq1Du

As you can see, the template bindings aren't correct. Right now, the template has bindings to one of the columns (Path="DataItem.Columns[0]"), since I can't figure out a simple way to get the index for each column into the template. What I really want is for the CellValuePresenter to get the correct bound object, defined in my FieldLayout, but bind each textbox to the appropiate property.

Any help would be vastly appreciated. Thanks, Ed

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           xmlns:igWPF="http://schemas.infragistics.com/xaml/wpf"
          xmlns:local="clr-namespace:WpfApplication2"
        Title="MainWindow" Height="350" Width="525">


    <Window.Resources>
        <ResourceDictionary>
            <local:InfoConverter x:Key="InfoConverter" />

            <Style TargetType="{x:Type igWPF:CellValuePresenter}" x:Key="InfoStyle">
                <Setter Property="BorderThickness" Value="2"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type igWPF:CellValuePresenter}">
                            <StackPanel>
                                <Border BorderBrush="Black" BorderThickness="2">
                                    <StackPanel>
                                        <StackPanel Orientation="Vertical">
                                            <Label Content="Name:" />
                                            <TextBox Text="{Binding Path=DataItem.Columns[0], ConverterParameter=name, Converter={StaticResource InfoConverter}}"/>
                                        </StackPanel>
                                        <StackPanel Orientation="Vertical">
                                            <Label Content="Age:" />
                                            <TextBox Text="{Binding Path=DataItem.Columns[0], ConverterParameter=age, Converter={StaticResource InfoConverter}}"/>
                                        </StackPanel>
                                    </StackPanel>                                        
                                </Border>                                    
                            </StackPanel>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ResourceDictionary>
    </Window.Resources>

    <Grid>
        <igWPF:XamDataGrid x:Name="Grid"  DataSource="{Binding Rows, Mode=TwoWay}">
            <igWPF:XamDataGrid.FieldLayouts>
                <igWPF:FieldLayout>
                    <igWPF:FieldLayout.Fields>

                    </igWPF:FieldLayout.Fields>
                </igWPF:FieldLayout>
            </igWPF:XamDataGrid.FieldLayouts>
            <igWPF:XamDataGrid.FieldLayoutSettings>
                <igWPF:FieldLayoutSettings SelectionTypeCell="Single" SelectionTypeRecord="Single" AutoGenerateFields="False"/>
            </igWPF:XamDataGrid.FieldLayoutSettings>
        </igWPF:XamDataGrid>
    </Grid>
</Window>


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;

namespace WpfApplication2
{
    class InfoConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string mode = parameter as string;
            Info info = value as Info;
            if (mode != null && info != null)
            {
                if (mode.Equals("name"))
                {
                    return info.Name;
                }
                else if (mode.Equals("age"))
                {
                    return info.Age;
                }
            }            
            return null;
        }

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

using Microsoft.Practices.Prism.ViewModel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace WpfApplication2
{
    public class RowViewModel :NotificationObject
    {
        public RowViewModel(params Info[] info) : base()
        {
            foreach (Info i in info){
                Columns.Add(i);   
            }
        }

        private ObservableCollection<Info> columns = new ObservableCollection<Info>();
        public ObservableCollection<Info> Columns
        {
            get
            {
                return columns;
            }
            set
            {
                columns = value;
                RaisePropertyChanged("Columns");
            }
        }
    }

      public class TableViewModel :NotificationObject
      {
        public TableViewModel() : base()
        {

            Rows.Add(new RowViewModel(new Info("A", 1), new Info( "B", 2), new Info("C", 3)));
            Rows.Add(new RowViewModel(new Info("D", 4), new Info( "E", 5), new Info("F", 6)));
            Rows.Add(new RowViewModel(new Info("G", 7), new Info("H", 8), new Info("I", 9)));
        }

        private ObservableCollection<RowViewModel> rows = new ObservableCollection<RowViewModel>();
        public ObservableCollection<RowViewModel> Rows
        {
            get
            {
                return rows;
            }
            set
            {
                rows = value;
                RaisePropertyChanged("Rows");
            }
        }
    }

      public class Info
      {
          public Info(string name, int age)
          {
              this.Name = name;
              this.Age = age;
          }

          public override string ToString()
          {
              return Name + " " + Age;
          }

          private string _name;
          public string Name
          {
              get
              {
                  return _name;
              }

              set
              {
                  _name = value;
              }
          }

          private int _age;
          public int Age
          {
              get
              {
                  return _age;
              }
              set
              {
                  this._age = value;
              }
          }
      }
}
Was it helpful?

Solution

Edit: I figured it out! I just bind to the Value of the CellValuePresenter.

<TextBox Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type igWPF:CellValuePresenter}}, Path=Value, ConverterParameter=name, Converter={StaticResource InfoConverter}}"/>

Hell, I don't even need the converter:

<TextBox Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type igWPF:CellValuePresenter}}, Path=Value.Age}"/>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top