Search code examples
wpfdata-bindingdatagrid

How to make only certain columns of certain rows editable in Datagrid


<Grid>
    <igDP:XamDataGrid x:Name="U_XamDataGrid"
                      BorderBrush="{DynamicResource BorderColorBrush}"
                      DataSource="{Binding GetData.MSInform}"
                      GroupByAreaLocation="None"
                      GroupByAreaMode="MultipleFieldLayoutsFull"
                      InitializeRecord="U_XamDataGrid_InitializeRecord"
                      IsGroupByAreaExpanded="True"
                      ScrollViewer.VerticalScrollBarVisibility="Visible"
                      Theme="Office2013">
        <igDP:XamDataGrid.Resources>
            <SolidColorBrush x:Key="{ComponentResourceKey {x:Type igDP:XamDataGrid}, LabelBackground}" Color="{DynamicResource BackColorWhite}" />
        </igDP:XamDataGrid.Resources>

        <igDP:XamDataGrid.FieldSettings>
            <igDP:FieldSettings AllowEdit="false" LabelClickAction="Nothing" />
        </igDP:XamDataGrid.FieldSettings>

        <igDP:XamDataGrid.FieldLayoutSettings>
            <igDP:FieldLayoutSettings AllowClipboardOperations="All"
                                      AutoFitMode="Always"
                                      AutoGenerateFields="False"
                                      CopyFieldLabelsToClipboard="True"
                                      HeaderPlacementInGroupBy="OnTopOnly"
                                      HeaderPrefixAreaDisplayMode="FieldChooserButton"
                                      RecordSelectorLocation="None" />
        </igDP:XamDataGrid.FieldLayoutSettings>

        <igDP:XamDataGrid.FieldLayouts>
            <igDP:FieldLayout Key="MeasureSetInformationsSt">
                <igDP:FieldLayout.SortedFields>
                    <igDP:FieldSortDescription Direction="Ascending"
                                               FieldName="Title"
                                               IsGroupBy="True" />
                </igDP:FieldLayout.SortedFields>

                <igDP:FieldLayout.Fields>
                    <igDP:Field Name="Title"
                                Width="Auto"
                                AllowGroupBy="True"
                                Visibility="Collapsed" />

                    <igDP:Field Name="Name"
                                Width="Auto"
                                Label="{x:Static lang:Lang.Name}" />

                    <igDP:TemplateField Name="Value" Label="{x:Static lang:Lang.Value}">
                        <igDP:TemplateField.Settings>
                            <igDP:FieldSettings AllowEdit="{Binding Path=DataContext.IsEditable, ElementName=xamDataGrid}" />
                        </igDP:TemplateField.Settings>
                        <igDP:TemplateField.DisplayTemplate>
                            <DataTemplate>
                                <TextBlock Text="{igEditors:TemplateEditorValueBinding}" />
                            </DataTemplate>
                        </igDP:TemplateField.DisplayTemplate>
                        <igDP:TemplateField.EditTemplate>
                            <DataTemplate>
                                <igEditors:XamComboEditor IsAlwaysInEditMode="True" Value="1" />
                            </DataTemplate>
                        </igDP:TemplateField.EditTemplate>
                    </igDP:TemplateField>
                </igDP:FieldLayout.Fields>
            </igDP:FieldLayout>
        </igDP:XamDataGrid.FieldLayouts>
            </igDP:FieldLayout>
        </igDP:XamDataGrid.FieldLayouts>-->
    </igDP:XamDataGrid>
</Grid>

I would like to allow only rows at a specific location to be editable.

*Viewmodel

public bool IsEditable { get; set; } = false;
public string Title { get; set; }
public string Name { get; set; }
public string Value { get; set; }


GetData.MSInform.Add(new MeasureSetInformationsSt()
{
    Title = Lang.MeasurementCondition,
    Name  = Lang.Mode,
    Value = probe.Mode.ToString(),
});

GetData.MSInform.Add(new MeasureSetInformationsSt()
{
    Title    = Lang.MeasurementCondition,
    Name     = Lang.Project,
    Value    = GetData.ProjectARC.Name,
});

GetData.MSInform.Add(new MeasureSetInformationsSt()
{
    Title      = Lang.MeasurementCondition,
    Name       = Lang.Probe,
    IsEditable = true,
    Value      = probe.No.ToString(),
});

GetData.MSInform.Add(new MeasureSetInformationsSt()
{
    Title    = Lang.MeasurementCondition,
    Name     = Lang.SpectrometerResolution,
    Value    = CommonMethod.GetDescriptionFromEnum((SPCTROMETER_RESOLUTION)(int)probe.SingleModeMeasureSetting.Resolution),
});

GetData.MSInform.Add(new MeasureSetInformationsSt()
{
    Title    = Lang.MeasurementCondition,
    Name     = Lang.BackgroundGainLevel,
    Value    = CommonMethod.GetDescriptionFromEnum((GAIN_LEVEL)probe.SingleModeMeasureSetting.BackgroundGain),
});

GetData.MSInform.Add(new MeasureSetInformationsSt()
{
    Title    = Lang.MeasurementCondition,
    Name     = Lang.SampleGainLevel,
    Value    = CommonMethod.GetDescriptionFromEnum((GAIN_LEVEL)probe.SingleModeMeasureSetting.SampleGain),
});

GetData.MSInform.Add(new MeasureSetInformationsSt()
{
    Title    = Lang.MeasurementCondition,
    Name     = Lang.Averaging,
    Value    = probe.SingleModeMeasureSetting.Averaging.ToString(),
});

GetData.MSInform.Add(new MeasureSetInformationsSt()
{
    Title    = Lang.MeasurementCondition,
    Name     = Lang.BoxcarWidthEnable,
    Value    = probe.SingleModeMeasureSetting.BoxcarWidthEnable.ToString(),
});

GetData.MSInform.Add(new MeasureSetInformationsSt()
{
    Title    = Lang.MeasurementCondition,
    Name     = Lang.BoxcarWidth,
    Value    = probe.SingleModeMeasureSetting.BoxcarWidth.ToString(),
});

IsEditable = true Only one part of the row must be editable in ComboBox form.I'm still not sure if it's right to do it this way. A binding error occurred in the output window. I don't know how to bind it properly. The error details are attached.

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=DataContext.IsEditable; DataItem=null; target element is 'FieldSettings' (HashCode=45408440); target property is 'AllowEdit' (type 'Nullable`1')


Solution

  •  <igDP:FieldSettings AllowEdit="{Binding Path=DataContext.IsEditable, ElementName=xamDataGrid}" />
    

    There are some questions that you need to clear up first:

    • Is "igDP" a UI library or a nugget packet you currently use? Did you check their source code or document/example on "XamDataGrid" (if it is available)
    • The binding error you posted here basically says that the compiler did not find the UI element you refer to. Are you sure that "xamDataGrid" is the control you want to bind with?

    Lastly, back to your question "allow only rows at a specific location to be editable", Do you mean that you want some rows to be editable if they meet certain conditions or requirements? If so then it would be easy to bind AllowEdit to a property from your ViewModel instead of the view and write your logic in the VM.