简体   繁体   中英

WPF DataGrid with ComboBox - Two-way binding requires Path or XPath

I have problems with a datagrid. When I'm triggering RowEditEnding event I receive the following error: "Two-way binding requires Path or XPath." I'm looking to fix this all day now, but couldn't find a solution. Any ideas welcome. Thanks in advance!

XAML

<Window.Resources>
    <staticData:AlarmFilesList x:Key="AlarmFilesList"/>
</Window.Resources>

XAML

<DataGrid x:Name="alarmProfilesDataGrid" Margin="10,60,10,50" AutoGenerateColumns="False" CanUserReorderColumns="False" CanUserResizeColumns="False" CanUserResizeRows="False">
                            <DataGrid.Columns>
                                <DataGridTextColumn Binding="{Binding AlarmTime, NotifyOnTargetUpdated=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Header="Alarm Time" Width="75" MinWidth="75"/>
                                <DataGridTemplateColumn Header="Alarm File"  Width="*" MinWidth="100">
                                    <DataGridTemplateColumn.CellTemplate>
                                        <DataTemplate>
                                            <TextBlock Text="{Binding AlarmFile}"/>
                                        </DataTemplate>
                                    </DataGridTemplateColumn.CellTemplate>
                                    <DataGridTemplateColumn.CellEditingTemplate>
                                        <DataTemplate>
                                            <ComboBox ItemsSource="{StaticResource AlarmFilesList}" SelectedItem="{Binding AlarmFileDescription}" SelectionChanged="ComboBox_SelectionChanged"/>
                                            <!--<ComboBox x:Name="AlarmFilesListComboBox" Text="{Binding AlarmFileDescription, NotifyOnSourceUpdated=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedValue="{Binding Id, NotifyOnSourceUpdated=True, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="AlarmFileDescription" SelectedValuePath="Id" Loaded="AlarmFilesListComboBox_Loaded"  />-->
                                        </DataTemplate>
                                    </DataGridTemplateColumn.CellEditingTemplate>
                                </DataGridTemplateColumn>
                            </DataGrid.Columns>
                        </DataGrid>

Here is the class that fills the ComboBox

class AlarmFilesList : List<string>
{
    BreakBuzzerEntities breakBuzzerContext = new BreakBuzzerEntities();
    public AlarmFilesList()
    {
        var alarmFiles = (from af in breakBuzzerContext.AlarmFiles select af).ToList();
        foreach (AlarmFile currentFile in alarmFiles)
        {
            this.Add(currentFile.AlarmFileDescription);
        }
    }
}

End here is also the relevant code

private void getSelectedAlarmProfile(AlarmProfileDefinition selectedAP)
    {
        Mouse.OverrideCursor = Cursors.Wait;
        List<AlarmProfileData> alarmProfileData = new List<AlarmProfileData>();
        var alarmProfileList = (from alarmProfile in breakBuzzerContext.AlarmProfiles
                                where alarmProfile.AlarmProfileDefinitionId == selectedAP.Id
                                select alarmProfile).ToList().OrderBy(x => x.AlarmTime);
        foreach (AlarmProfile alarmProfileItem in alarmProfileList)
        {
            alarmProfileData.Add(new AlarmProfileData { AlarmTime = alarmProfileItem.AlarmTime, AlarmTimeId=alarmProfileItem.Id, AlarmFile=alarmProfileItem.AlarmFile.AlarmFileDescription, AlarmFileId=alarmProfileItem.AlarmFileId });
        }
        alarmProfilesDataGrid.ItemsSource = null;
        alarmProfilesDataGrid.ItemsSource = alarmProfileData;
        alarmProfilesDataGrid.DataContext = this;
        Mouse.OverrideCursor = null;
    }

    public class AlarmProfileData
    {
        public TimeSpan AlarmTime { get; set; }
        public int AlarmTimeId { get; set; }
        public string AlarmFile { get; set; }
        public int AlarmFileId { get; set; }
    }
    private void alarmProfilesDataGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
    {
        var apData = alarmProfilesDataGrid.SelectedItem;
        if (apData != null)
        {

        }
    }

If you are following MVVM, You have to add ItemsSource="{Binding alarmProfileData}" if you are following Classic pattern then you need to add ItemsSource="{Binding}" as attribute with your grid. in order to show that the grid is binding dynamically. hence your grid Definition will be like :

<DataGrid x:Name="alarmProfilesDataGrid" ItemsSource="{Binding}" Margin="10,60,10,50" AutoGenerateColumns="False" CanUserReorderColumns="False" CanUserResizeColumns="False" CanUserResizeRows="False">

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM