C # WPF - Добавление изображения в набор данных или сетку данных - код только позади - PullRequest
0 голосов
/ 30 ноября 2018

У меня есть сетка данных, которая определена в начале

 DataGrid dtgWatch;

и связана с набором данных dtsWatch;

dtgWatch.ItemsSource = dtsWatch.Tables[0].DefaultView;

посередине набор данных заполнен строками с

 dtsWatch.Tables[0].Rows.Add(string1, string2);

Цель - что-то вроде следующей вкладки:

|string1_A |string2_A |

|string1_B |string2_B |

|string1_B |string2_C |

, который работает правильно.Теперь изменение: в точке этого рассуждения (и только для одной строки) я должен поместить изображение, а не строку.Это означает:

|string1_A |string2_A |

|string1_B |Image2_B |<--------------- </p>

|string1_B |string2_C |

Теоретически это должно работать (без ошибки компиляции), так как в случае изображения я добавляю строку с

Image img =...
dtsWatch.Tables[0].Rows.Add(string1, img);

, но результат равен

|строка1 |System.Windows.Controls.Image |


Возможное решение, о котором я подумал, - поместить где-нибудь маркер, а затем во время выполнения (событие загрузки строки или что-то в этом роде) изменитьсодержимое ячейки с изображением.К сожалению, я мог сделать это, потому что я мог получить прямой доступ и изменить ячейку.


Я делаю все это с C # wpf с помощью appdomain tecnique.Это означает, что у меня нет xaml, я должен делать все в коде позади.Все, что у меня есть, - это сетка для добавления в сетку данных.


Я пытался , что , но оно не завершено, и все другие решения, которые я нашел, подразумевали использование xaml


Спасибо за любыепомощь

Патрик

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

ОК. Я выбрал другой подход:

private void Dg_Loaded(object sender, RoutedEventArgs e)
{
    for (int i = 0; i < dg.Items.Count; i++)
    {
        DataGridRow row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(i);
        for (int j = 0; j < dg.Columns.Count; j++)
        {
            TextBlock cellContent = dg.Columns[j].GetCellContent(row) as TextBlock;
            var strContent = cellContent.Text;
            if (strContent == "BBB2")
            {
                    // This if I want merely change the value (not my case)
                    //cellContent.Text = "XXXX";

                    //This if I want to put an image
                    var dtgCell = cellContent.Parent as DataGridCell;
                    dtgCell.Content = new Image() { Source = new BitmapImage(new Uri(@"C:\Users\Pictures\Ball_Red.png")) };
                }
            }
        }
    }

Поэтому, вместо того, чтобы пытаться изменить DTG ДО показа, я изменяю его ПОСЛЕ.

0 голосов
/ 30 ноября 2018

Для достижения желаемого поведения вы должны создать свои DataGridColumns вручную.

Вы все еще можете написать Xaml, потому что вы можете легко анализировать и создавать соответствующие объекты в коде позади.См. System.Windows.Markup.XamlReader.Load

Так что это должно работать для вас

dtgWatch.AutoGenerateColumns = false;
foreach (DataColumn column in dtsWatch.Tables[0].Columns)
{
    string dataGridTemplateColumn = $@"
    <DataGridTemplateColumn
        Header=""{column.ColumnName}""
        xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
        xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" >
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <ContentControl Content=""{{Binding {column.ColumnName}}}"" />
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>";
    XmlReader xr = XmlReader.Create(new StringReader(dataGridTemplateColumn));
    dtgWatch.Columns.Add((DataGridTemplateColumn)System.Windows.Markup.XamlReader.Load(xr)); 
}
...