I am using MVVM and bind a DataGrid
to an ObservableCollection<CustomClass>
. I can successfully do that, however I want one of the DataGrid
columns to be a ComboBox
column, with items source List<ComboBoxValues>
. Also another column must be a ToggleSwitch
where a Command
with parameter is fired when it's IsOn
property changes value.
In the ViewModel:
public ObservableCollection<CustomClass> DataGridData { get; set; } = new ObservableCollection<CustomClass>();
public List<ComboBoxValues> ListValues { get; set; } = new List<ComboBoxValues>();
public MyICommand<ToggleSwitch> ToggleSwitchToggled_Command { get; private set; }
The problem I am getting is that the DataGrid
's ItemsSource
Binding
is overriding the Binding
path for the CombobBox
's ItemsSource
, as well as the Command
's Binding
. ListValues
and ToggleSwitchToggled_Command
is looked for within DataGridData
.
For example:
Error: BindingExpression path error: 'ListValues' property not found on 'UWPProject.ViewModels.DataGridData'. BindingExpression: Path='ListValues' DataItem='UWPProject.ViewModels.DataGridData'; target element is 'Windows.UI.Xaml.Controls.ComboBox' (Name='null'); target property is 'ItemsSource' (type 'Object')
In Xaml:
<controls:DataGrid GridLinesVisibility="All"
AlternatingRowBackground="Gray" AutoGenerateColumns="False"
ItemsSource="{Binding DataGridData,Mode=TwoWay}">
<controls:DataGrid.Columns>
<controls:DataGridTextColumn Header="TextOne" Binding="{Binding aPropertyOneInDataGridData,Mode=TwoWay}"/>
<controls:DataGridTextColumn Header="TextTwo" Binding="{Binding aPropertyTwoInDataGridData,Mode=TwoWay}"/>
<controls:DataGridTemplateColumn Header="ComboBoxHeader">
<controls:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<ComboBox ItemsSource="{Binding ListValues}"
SelectedValue="{Binding aPropertyThreeInDataGridData,Mode=TwoWay}"
PlaceholderText="Select Action">
</ComboBox>
</StackPanel>
</DataTemplate>
</controls:DataGridTemplateColumn.CellTemplate>
</controls:DataGridTemplateColumn>
<controls:DataGridTemplateColumn Header="ToggleSwitch_Header">
<controls:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<ToggleSwitch x:Name="ToggelSwitch_Run"
IsOn="{Binding aPropertyFourInDataGridData,Mode=TwoWay}">
<interact:Interaction.Behaviors>
<interactcore:EventTriggerBehavior EventName="Toggled">
<interactcore:InvokeCommandAction Command="{Binding ToggleSwitchToggled_Command}"
CommandParameter="{Binding}"/>
</interactcore:EventTriggerBehavior>
</interact:Interaction.Behaviors>
</ToggleSwitch>
</StackPanel>
</DataTemplate>
</controls:DataGridTemplateColumn.CellTemplate>
</controls:DataGridTemplateColumn>
</controls:DataGrid.Columns>
</controls:DataGrid>
So I guess, the question is, how do I split the "source" or path where the Binding
is looked for within the parent DataGrid
. There are many WPF
questions and answers on this, such as here and here. however I can't use DataContext
, as I get the error that "DataContext is not supported in a UWP project
." I can't find a solution for a UWP project for this problem. Also, I am using MVVM and no code behind, so I don't believe I can use x:Binding
. I don't want to use code behind either.
Please help.
For your scenario, we suggest use DataGridComboBoxColumn
to replace custom celltemplate. Then you could use x:bind markup extension to bind list property directly.
Because DataGridComboBoxColumn
ItemsSource property could not access data source sub property directly, If you already make ListValues
property for the Page class, you could also use x:bind to access like the following.
<controls:DataGridComboBoxColumn
Width="*"
Binding="{Binding p2}"
Header="Link"
ItemsSource="{x:Bind ListValues ,Mode=OneWay}"
Tag="Link"
/>
If you do want to make custom celltemplate, you could insert the ListValues property into your CustomClass
. For more detail please refer this case reply.