将图像控件绑定到数据网格数据上下文(视图模型)

Binding an Image control to a datagrids datacontext (viewmodel)

我有一个绑定到 CollectionViewSource 的 WPF DataGrid。查看源包含一些关于出租物业的数据,即地址和图像 属性。 DataGrid 显示地址信息,但图像是通过 DataGrid 之外的 Image 控件显示的。此 Image 控件绑定到与 DataGrid 相同的数据 DataContext。这个想法是,当用户在 DataGrid 中选择一行时,图像会更改为 属性 的图像。 Select 不同的行 (属性) 并且图像发生变化(我将 Image 控件放在 DataGrid 之外,因为显示每个图像都会使网格相当大)。默认情况下,DataGrid 是只读的,行选择单位为 'fullrow'。到目前为止,所有工作都按要求进行。我有一个 Button 允许用户编辑网格,这会将网格更改为可编辑,行选择单位为 'cell'。

现在它倒下了,图像消失了,似乎不再有 link 回到 DataContext。我猜有些魔法是 link 将数据网格的选定项目返回到视图源,这允许图像 属性 可用于我的 Image 控件但是一旦行选择单元格更改 DataGrid.

中不再有选定项目

当我使网格可编辑时,如何使图像保持可见?

我不是专业程序员,正在为 'fun' 学习 WPF 和 C#。 万分感谢

DataGrid 的相关标记:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:Entities="clr-namespace:wpfPortfolioManager.Entities"
    xmlns:local="clr-namespace:wpfPortfolioManager"
    xmlns:DataSets="clr-namespace:wpfPortfolioManager.DataSets"
    xmlns:dsAllTablesTableAdapters="clr-namespace:wpfPortfolioManager.DataSets.dsAllTablesTableAdapters" x:Name="window" x:Class="wpfPortfolioManager.Forms.HomeScreen"
    mc:Ignorable="d"
    Title="HomeScreen" SizeToContent="WidthAndHeight" Loaded="Window_Loaded" >
    <Window.Resources>
        <CollectionViewSource x:Key="propertyViewSource" d:DesignSource="{d:DesignInstance {x:Type Entities:Property}, CreateList=True}"/>
    </Window.Resources>

    <TabItem x:Name="tabProperties" Header="Properties" DataContext="{StaticResource propertyViewSource}" Background="{x:Null}" >
        <Grid Background="#FFDA4D2E" ScrollViewer.CanContentScroll="True" ShowGridLines="False">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="98"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <StackPanel Grid.Column="0" Orientation="Vertical" Width="{Binding ElementName=buttonSaveProperties, Path=Width}" HorizontalAlignment="Left" VerticalAlignment="Top" Height="78">
                <Button x:Name="buttonSaveProperties" IsEnabled="{Binding ElementName=propertyDataGrid, Path=IsReadOnly, Converter={StaticResource convertBoolean}}" Click="buttonSaveProperties_Click" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,5">
                    <StackPanel Orientation="Horizontal" Width="90">
                        <Image   Stretch="Fill" Width="25" Height="25" Margin="0" Source="Save_16x.png"/>
                        <TextBlock Text="Save" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,0,0,0"/>
                    </StackPanel>
                </Button>

                <Button  x:Name="buttonCancel" Margin="2,5" IsEnabled="{Binding ElementName=propertyDataGrid, Path=IsReadOnly, Converter={StaticResource convertBoolean}}" Click="buttonCancelProperty_Click">
                    <StackPanel Orientation="Horizontal" Width="90">
                        <Image   Stretch="Fill" Width="25" Height="25" Margin="0" Source="stop.png"/>
                        <TextBlock Text="Cancel" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10,0,0,0"/>
                    </StackPanel>
                </Button>
            </StackPanel>

            <StackPanel Grid.Column="1" Orientation="Horizontal" Width="Auto">
                <Button x:Name="buttonMakeEditable" Click="buttonMakePropertiesEditable_Click"  VerticalAlignment="Top" Margin="0,0,0,0" Width="30" Height="30"  HorizontalAlignment="Left" >
                    <Image Source="i_edit-itemBlue_F12.png"  Stretch="Fill" Width="25" Height="25" Margin="1"/>
                </Button>
                <DataGrid x:Name="propertyDataGrid" ItemsSource="{Binding}" SelectedItem="{Binding SelectedProperty}" Style="{DynamicResource ReadOnlyDataGridStyle}"  HorizontalAlignment="Left" RowHeaderWidth="20">
                    <DataGrid.Columns>
                        <DataGridTextColumn x:Name="propertyNameColumn" Width="Auto" Header="Property" Binding="{Binding PropertyName}"/>
                        <DataGridTextColumn x:Name="address1Column" Width="Auto" Header="Street" Binding="{Binding Address1}"/>
                        <DataGridTextColumn x:Name="address2Column" Width="Auto" Header="Town" Binding="{Binding Address2}"/>
                        <DataGridTextColumn x:Name="address3Column" Width="Auto" Header="County" Binding="{Binding Address3}"/>
                        <DataGridTextColumn x:Name="address4Column" Width="Auto" Header="Post Code" Binding="{Binding Address4}"/>
                        <DataGridTemplateColumn x:Name="columnNewPicture" Header="New Picture"  Visibility="Collapsed" >
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <Button x:Name="buttonNewPicture" Click="buttonNewPicture_Click" CommandParameter="{Binding Path=PropertyID}" Height="10" IsEnabled="{Binding ElementName=propertyDataGrid, Path=IsReadOnly, Converter={StaticResource convertBoolean}}"></Button>
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
                    </DataGrid.Columns>
                </DataGrid>
                <Border BorderBrush="#FF6EA410" BorderThickness="2" Height="150" Width="150" HorizontalAlignment="Left" VerticalAlignment="Top" >
                    <Image x:Name="testImage" Source="{Binding Image}" HorizontalAlignment="Left" Margin="4,0,0,0" VerticalAlignment="Top" Width="150" Height="150"/>
                </Border>
            </StackPanel>
        </Grid>
    </TabItem>

<!-- Rest of the xaml file -->

</Window>

DataGrid 风格:

<Style x:Key="BaseDataGridStyle" TargetType="DataGrid">

    <!--#region Grid -->
    <Setter Property="HorizontalAlignment" Value="Left"/>
    <Setter Property="VerticalAlignment" Value="Top"/>
    <Setter Property="AutoGenerateColumns" Value="False"/>
    <Setter Property="GridLinesVisibility" Value="None"/>
    <Setter Property="IsReadOnly" Value="True"/>
    <Setter Property="Margin" Value="0"/>
    <Setter Property="Width" Value="Auto"/>
    <Setter Property="BorderThickness" Value="1"/>
    <!--#endregion-->

    <!--#region Font -->
    <Setter Property="FontFamily" Value="Arial"/>
    <Setter Property="FontSize" Value="14"/>
    <Setter Property="FontWeight" Value="DemiBold"/>
    <!--#endregion-->

    <!--#region Height & Width -->
    <Setter Property="MinHeight" Value="50 "/>
    <Setter Property="MaxHeight" Value="800"/>
    <!--<Setter Property="MinWidth" Value="600"/>-->
    <Setter Property="MaxWidth" Value="1200"/>
    <Setter Property="Width" Value="Auto"/>
    <Setter Property="Height" Value="Auto"/>
    <!--#endregion-->

    <!--#region Columns -->
    <Setter Property="ColumnHeaderStyle" Value="{DynamicResource DataGridColumnHeader}"/>
    <Setter Property="ColumnWidth" Value="Auto"/>
    <Setter Property="CanUserReorderColumns" Value="False"/>
    <Setter Property="CanUserResizeColumns" Value="False"/>
    <!--#endregion-->

    <!--#region Rows -->
    <!--<Setter Property="RowBackground" Value="Red"/>-->
    <Setter Property="SelectionUnit" Value="FullRow"/>
    <!--<Setter Property="CellStyle" Value="{DynamicResource DataGridCellText}"/>-->
    <Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected"/>
    <!--#endregion-->

    <!--<Setter Property="RowStyle" Value="{DynamicResource DataGridRowStyle1}"/>-->
    <Setter Property="CellStyle" Value="{DynamicResource DataGridCellStyle1}"/>
</Style>

<Style x:Key="ReadOnlyDataGridStyle"  BasedOn="{StaticResource  BaseDataGridStyle}" TargetType="DataGrid">
    <!--#region Grid -->

    <Setter Property="BorderBrush" Value="Red"/>
    <!--#endregion-->

    <!--#region Rows -->
    <Setter Property="CanUserAddRows" Value="False"/>
    <Setter Property="CanUserDeleteRows" Value="False"/>
    <Setter Property="CanUserResizeRows" Value="False"/>
    <!--#endregion-->

</Style>

<Style x:Key="EditableDataGridStyle" BasedOn="{StaticResource  BaseDataGridStyle}" TargetType="DataGrid">
    <!--#region Grid -->
    <Setter Property="SelectionUnit" Value="Cell"/>
    <Setter Property="IsReadOnly" Value="False"/>
    <Setter Property="BorderBrush" Value="Green"/>
    <!--#endregion-->

    <!--#region Rows -->
    <Setter Property="CanUserAddRows" Value="True"/>
    <Setter Property="CanUserDeleteRows" Value="True"/>
    <!--#endregion-->
</Style>

<Style x:Key="DataGridColumnHeader" TargetType="DataGridColumnHeader">
    <!--#region Column Header -->
    <Setter Property="FontFamily" Value="Arial"/>
    <Setter Property="FontSize" Value="16"/>
    <Setter Property="FontWeight" Value="DemiBold"/>
    <Setter Property="HorizontalAlignment" Value="Center"/>
    <!--#endregion-->
</Style>

<Style x:Key="DataGridCellText" TargetType="DataGridCell">
    <!--#region Cell -->
    <Setter Property="Margin" Value="5, 5"/>
    <Setter Property="HorizontalAlignment" Value="Center"/>
    <Setter Property="VerticalAlignment" Value="Center"/>
    <Setter Property="MinWidth" Value="40"/>
    <!--#endregion-->
</Style>

DataContext设置为:

private void InitialiseDataContext()
{
    CollectionViewSource propertyViewSource = ((CollectionViewSource)(FindResource("propertyViewSource")));
    CollectionViewSource tenantViewSource = ((CollectionViewSource)(FindResource("tenantViewSource")));

    _context.Properties.Load();
    _context.Tenants.Load();

    propertyViewSource.Source = _context.Properties.Local;
    tenantViewSource.Source = _context.Tenants.Local;
}

DataGrid 可通过以下代码编辑:

dgEditable = (Style)FindResource("EditableDataGridStyle");
dgReadonly = (Style)FindResource("ReadOnlyDataGridStyle");

private void buttonMakePropertiesEditable_Click(object sender, RoutedEventArgs e)
{
    propertyDataGrid.Style = propertyDataGrid.Style == dgEditable ? dgReadonly : dgEditable;
    foreach (var item in propertyDataGrid.Columns)
    {
        if (item.Header.ToString() == "New Picture")
        {
            item.Visibility = item.Visibility == Visibility.Collapsed ? Visibility.Visible : Visibility.Collapsed;
        }
    }
}

你的代码看起来很合理,即使你没有显示一些东西,比如 Image 控件绑定到什么。

无论如何,我发现 SelectionUnit = Celllook here.

有问题

解决方案可以是其中之一,或者您可以将代码更改为仅使用 SelectionUnit = FullRow

我不知道你为什么需要 Cell 作为 SelectionUnit 但如果主要关心的是编辑单个单元格,你仍然可以在 FullRow 中完成。

这样您就不必编写一些花哨的代码来解决这个问题。

希望对您有所帮助。