Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > WPF и Silverlight > DataGrid сзязать данными две колонки


Автор: Человек01 22.2.2009, 14:28
Диспозиция:
DataGrid с данными из базы, добавляется две колонки одна колонка забивается данными MyClass 
Код

MySqlDataAdapter adap  = new MySqlDataAdapter(sql, cbild.ConnectionString);
DataSet ds = new DataSet();
adap.Fill(ds);
ds.Tables[0].Columns.Add("Myclasscolumn", typeof(MyClass));
ds.Tables[0].Columns.Add("newcollumn", typeof(int));
datagrid1.ItemsSource = ds.Tables[0].DefaultView;
datagrid1.Columns[datagrid1.Columns.Count - 1] = (DataGridTemplateColumn)this.Resources["templateNewcollumn"];
datagrid1.Columns[datagrid1.Columns.Count - 2]  = (DataGridTemplateColumn)this.Resources["templateMyClasscollumn"];
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
         dtt.Rows[i].SetField(dtt.Columns["Myclasscolumn"], new MyClass(i));
}


Код

public class MyClass
{
    public MyClass(int i)
    {
         level = i;
    }
    private int level;
    public int Level
   {
        get{ retrun level; }
        sel { level =value; }
   }
}


Код

<wpf:DataGridTemplateColumn x:Key="templateNewcollumn" Header="Новая колонка" Width="200" CanUserSort="True">            
            <wpf:DataGridTemplateColumn.CellTemplate>
                <DataTemplate DataType="int">
                    <WrapPanel>
                        <TextBlock Text="{Binding Path=Myclasscolumn.Level}"/>
                    </WrapPanel>
                </DataTemplate>
            </wpf:DataGridTemplateColumn.CellTemplate>
</wpf:DataGridTemplateColumn>

<wpf:DataGridTemplateColumn x:Key="templateMyClasscollumn" Header="Колонка с MyClass" Width="200" CanUserSort="True">            
            <wpf:DataGridTemplateColumn.CellTemplate>
                <DataTemplate DataType="evrika:MyClass">
                    <WrapPanel>
                        <TextBlock Text="{Binding Path=Myclasscolumn.Level}"/>
                    </WrapPanel>
                </DataTemplate>
            </wpf:DataGridTemplateColumn.CellTemplate>
</wpf:DataGridTemplateColumn>


Соответственно отображается все красиво и правильно, но в самой таблице в колонке newcollumn данных нет пусто.
Вопрос: Как сделать так чтобы данные в самой колонке (ds.Tables[0].Rows[i].GetField(dtt.Columns["newcollumn"]) были идентичными отображаемым в данной колонке.


Автор: Partizan 22.2.2009, 15:50
Человек01, а может стоит попробовать выставить у Binding Mode=TwoWay

Автор: Человек01 22.2.2009, 16:29
Немного не понял, ведь если я выставлю Mode=TwoWay то это будет просто говорить колонке(Myclasscolumn) содержащей элементы MyClass что требуется обновлять значения в соответствии с биндингом {Binding Path=Myclasscolumn.Level}, а у меня то проблема в том что колонка newcollumn отображать то отображает данные (в соответствии с этим Binding ом), но в самой таблице этих данных не появляется:
Код

for(int i=0;i< ds.Tables[0].Rows.Count;i++)
      Console.WriteLn("row["+i+"]"ds.Tables[0].Rows[i].GetField(dtt.Columns["newcollumn"] );


выдает:
Цитата

row[0]=
row[1]=
row[2]=
row[3]=
....


то есть непосредственно в таблице данных нет, вот мне и интересно как заставить их появляться там.
Если утрировать задачу то получается, есть две переменных
int i1;
int i2;
как сделать так чтобы при изменении любой из переменных, вторая меняла своё значение.


Автор: Partizan 22.2.2009, 16:58
Человек01, я тоже немного не понял....есть датагрид...в нём есть колонка, которая посредством биндинга отображает данные из табличной колонки newcolumn...что мешает в этом биндинге прописать Mode=TwoWay...в таком случае при изменении значения в UI, изменения будут происходить и в источнике данных..

Автор: Человек01 22.2.2009, 17:25
Это видимо я не правильно сформулировал вопрос. 
Правильнее спросить как связать две колонки в DataTable
1.заполнил DataTable данными из базы.
2.Добавил ещё колонку к DataTable.
3.Как сделать так чтобы эта новая колонка дублировала данные из первой колонки.
4.И при изменении данных в какой либо из этих колонок они автоматом менялись в другой.

Я сделал так после заполнения DataTable из базы, добавляю колонку и прохожусь по всем элементам и инициирую данные новой колонки(другими словами заполняю их).
Вешаюсь на событие изменения данных в строке(dtt.RowChanged += new DataRowChangeEventHandler(dtt_RowChanged)), если они изменились то провожу исследование изменений и соответственно меняю значения в том или ином столбце.

Но я хотел бы узнать есть ли какой нибудь другой способ, так сказать более изящный.  smile 

Автор: Partizan 22.2.2009, 17:54
Человек01, какой смысл иметь две колонки с абсолютно одинаковыми данными? К чему эта избыточность?

Автор: Человек01 22.2.2009, 19:15
Ну это же утрированная задача.
В первом посте я же написал. В посте MyClass тоже утрирован, само собой.
MyClass помимо вычислительных и обеспечительных мер занимается ещё и предоставлением данных для сортировки, а именно необходимой позиции строки в DataGrid, соответственно данные не являются избыточными. 
А может просто у меня не хватает знаний как реализовать сортировку в столбце, без нахождения там данных.

Автор: Partizan 23.2.2009, 21:24
Человек01, кажется я таки понял...по сути вам нужен байндинг одновременно к двум свойствам...
как вариант - можно чуть извратиться и написать собственный MarkupExtension + ещё немножко кода ;)

Можно ли получить такой функционал "искаропки" мне, к сожалению, не известно...

Автор: Человек01 23.2.2009, 21:47
Теперь хватило знаний чтобы сделать сортировку в колонке содержащей MyClass и как следствие отпала необходимость в создании дополнительной колонки в DataTable и всяческом связывании колонок, как правильно сказал Partizan эта избыточность не нужна.
Щас скажу как сделал, может кто тоже столкнулся с таким вопросом (хотя если я столкнулся с ним, явно хоть один человек им тоже задавался  smile )

Во первых:
в выставляем для нашей колонки 
Код

SortMemberPath="Myclasscolumn" CanUserSort="True" 


Во вторых в MyClass реализуем интерфейс IComparable
Код

public class MyClass : IComparable
{
   public int numRow=0;
   public int CompareTo(object obj)
   {
            if (obj is MyClass)
            {
                MyClass myclass = (MyClass)obj;
                return this. numRow.CompareTo(myclass. numRow);
            }
            else
            {
                throw new ArgumentException("не MyClass");
            }
   }
}


И всё, теперь можно нормально сортировать колонку содержащую экземпляры MyClass.  smile 
Оказалось очень просто и не надо было усложнять себе жизнь. 
P.S.:Тему не помечаю как решенную, т.к. может и правда существует способ связать данные двух колонок DataTable.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)