c#wpf DataGrid:以编程方式更改绑定列上的图像源

时间:2017-01-04 12:53:55

标签: c# wpf datagrid

我有一个SQL数据库,其计算机名称绑定到DataGrid,如下所示:

                <Grid.Resources>
            <ResourceDictionary>
                <local:FileIconConverter2 x:Key="FileIconConverter2"/>
                <BitmapImage x:Key="Image-Unknown" UriSource="../Images/Status-Unknown.ico" />
                <BitmapImage x:Key="Image-Good" UriSource="../Images/Status-Good.ico" />
            </ResourceDictionary>
        </Grid.Resources>
    <DataGrid Name="datagrid1" AutoGenerateColumns="False" IsReadOnly="True" SelectionChanged="datagrid1_SelectionChanged">
<DataGrid.Columns>
    <DataGridTemplateColumn Header="Status" >
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <Image Source="{StaticResource Image-Unknown}"/>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
    <DataGridTextColumn Header="Date d m yyyy" Binding="{Binding 'Date d m yyyy'}"/>
    <DataGridTextColumn Header="Device Name" Binding="{Binding DeviceName}"/>
    <DataGridTextColumn Header="OS" Binding="{Binding OS}"/>
    <DataGridTextColumn Header="OS" Binding="{Binding Model}"/>
    <DataGridTextColumn Header="EOL" Binding="{Binding DeviceAge}"/>
    <DataGridTextColumn Header="Location" Binding="{Binding Location}"/>
    <DataGridTextColumn Header="IP" Binding="{Binding IP}"/>
    <DataGridTextColumn Header="MAC" Binding="{Binding Mac}"/>
</DataGrid.Columns>

我要做的是当您点击一行时,让状态列图像更新以通过更改图像来显示计算机是否在线。 “状态”列不在数据库中。 每当我尝试更改状态列的内容时,我得到[icon]或[bitmap]文本,而不是图像,如果我向下滚动,则备份图像默认值。

这是 有什么建议吗?

编辑: 如果表可以包含100个条目,我只想在选择行时检查在线状态。所以我试图在datagrid1上使用SelectionChanged事件,如下所示:

    private void datagrid1_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        DataGrid dataGrid = sender as DataGrid;
        DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(dataGrid.SelectedIndex);
        DataGridCell rowColumn = dataGrid.Columns[2].GetCellContent(row).Parent as DataGridCell;
        string CellValue = ((TextBlock)rowColumn.Content).Text;
        log.Warn(CellValue);

        //myclass.GetCell(datagrid1, row.GetIndex(), 0).Content = Properties.Resources.Status_Good;
        myclass.GetCell(datagrid1, row.GetIndex(), 0).Content = (Bitmap)System.Drawing.Image.FromFile(@".\Images\Status-good.ico");

    }

myClass.GetCell代码来自此post.

但是,正如你在这个屏幕截图中看到的那样,我只得到文字而不是图像。 Screen Shot

1 个答案:

答案 0 :(得分:0)

您是否尝试为图片添加触发器?

<DataGridTemplateColumn Header="Status" >
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <Image >
               <Image.Style>
                   <Setter Property="Source" Value="{StaticResource Image-Unknown}"/>
                   <Style.Triggers>
                     <DataTrigger Binding="{Binding YourModelPropertyStatus}" Value="true">
                          <Setter Property="Source" Value="{StaticResource Image-Good}"/>
                     </DataTrigger>
                   </Style.Triggers>
               </Image.Style>
            </Image> 
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

修改:

解决方案1(最接近现有代码)

不是在后面的代码中搜索和编辑单元格内容(这是非常糟糕的做法),而是使用selectionChanged回调给出的参数,如e.AddedItemse.RemovedItems,它将为您提供商业模型(代表你的设备)已被添加和删除。像

这样的东西
        foreach (var addedItem in e.AddedItems)
        {
            var device = (Device) addedItem;
            device.CheckStatus();
        }
        foreach (var remItem in e.RemovedItems)
        {
            var device = (Device)remItem;
            device.SetToUnknown();
        }

其中CheckStatus是检查在线状态的方法,并将标志YourModelPropertyStatus设置为true为false(从而激活上述触发器)

解决方案2(最干净的方式)

在XAML中保留触发器解决方案的最佳和最干净的方法是使用CollectionView来管理您的设备集合,从而管理视图模型上的所有内容。 在您的XAML DataGrid中设置IsSynchronizedToCurrentItem=true,然后在您的视图模型中订阅CurrentChanged事件,并在回调中获取CollectionView的CurrentItem并调用CheckStatus();可以在视图模型中,也可以在设备对象中。