Reputation: 316
I have a datagrid where I change a cell depending on what is chosen from the other column.
Let's say, my first column shows Weekdays (enums). If the user choose "Monday", the cell in the second column will be a TextBox. If the user chosoe a different day(eg. Friday), it'll become a Textblock with Text="Hooray!", else Textblock Text="".
Both Textbox and Textblock binds in the same property. But this binding does not work. Please help...
XAML
<DataGrid Margin="0,10,0,0"
x:Name="dataGrid"
AutoGenerateColumns="False"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding TheCollection}"
SelectedItem="{Binding TheSelectedItemFromTheCollection}">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Days"
CanUserReorder="False"
CanUserResize="False"
CellTemplate="{StaticResource local.DataGridDays}" />
<DataGridTemplateColumn Header="Value"
CanUserReorder="False"
CanUserResize="False"
CellTemplate="{StaticResource local.DataGridValue}" />
</DataGrid.Columns>
</DataGrid>
<DataTemplate x:Key="local.DataGridValuesEditable">
<StackPanel>
<Border Background="White"
BorderThickness="1"
Padding="4">
<TextBox Text="{Binding InitialValue, RelativeSource={RelativeSource Self}, UpdateSourceTrigger=PropertyChanged}"
VerticalAlignment="Bottom"
Margin="0" />
</Border>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="local.DataGridValuesDefault">
<StackPanel>
<Border Background="White"
BorderThickness="1"
Height="30"
Padding="4">
<TextBlock Text="{Binding InitialValue, Mode=TwoWay, RelativeSource={RelativeSource Self}, UpdateSourceTrigger=PropertyChanged}"
VerticalAlignment="Bottom"
Margin="0"
Width="55" />
</Border>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="local.DataGridValue">
<ContentControl>
<ContentControl.Style>
<Style TargetType="ContentControl">
<Setter Property="ContentTemplate"
Value="{DynamicResource local.DataGridValuesDefault}" />
<Style.Triggers>
<DataTrigger Binding="{Binding SelectedDay, UpdateSourceTrigger=PropertyChanged}"
Value="Monday">
<Setter Property="ContentTemplate"
Value="{DynamicResource local.DataGridValuesEditable}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
ViewModel
private ObservableCollection<TheModel> _theCollection;
public ObservableCollection<TheModel> TheCollection
{
get
{
if (_theCollection == null)
_theCollection = new ObservableCollection<TheModel>();
return _theCollection;
}
set
{
_theCollection = value;
}
}
private TheModel _theSelectedItemFromTheCollection;
public TheModel TheSelectedItemFromTheCollection
{
get
{
if (_theSelectedItemFromTheCollection == null)
_theSelectedItemFromTheCollection = new TheModel();
return _theSelectedItemFromTheCollection;
}
set
{
_theSelectedItemFromTheCollection = value;
NotifyPropertyChanged("TheSelectedItemFromTheCollection");
}
}
Model
public string SelectedDay
{
get { return day; }
set
{
day = value;
if (day == TheWeekDays.Friday.ToString())
{
InitialValue = "Hooray!!";
}
else
InitialValue = string.Empty;
NotifyPropertyChanged("SelectedDay");
}
}
private string _initialValue;
public string InitialValue
{
get { return _initialValue; }
set
{
_initialValue = value;
NotifyPropertyChanged("InitialValue");
}
}
public IEnumerable<WeekDays> TheWeekDays
{
get
{
return Enum.GetValues(typeof(WeekDays))
.Cast<WeekDays>();
}
}
Upvotes: 0
Views: 142
Reputation: 13438
The following is the desired situation:
The DataContext
of local.DataGridValuesDefault
and local.DataGridValuesEditable
should be the row item TheModel
.
With this DataContext
, the bindings can be written as follows:
<TextBox Text="{Binding InitialValue,UpdateSourceTrigger=PropertyChanged}"
and
<TextBlock Text="{Binding InitialValue}"
The DataContext
of local.DataGridValue
contains the desired item. A ContentControl
will turn its Content
into the DataContext
of its ContentTemplate
, so the Content
needs to be linked with the outer DataContext
. Also, the trigger binding can be simplified:
<DataTemplate x:Key="local.DataGridValue">
<ContentControl Content="{Binding}">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Setter Property="ContentTemplate"
Value="{DynamicResource local.DataGridValuesDefault}" />
<Style.Triggers>
<DataTrigger Binding="{Binding SelectedDay}"
Value="Monday">
<Setter Property="ContentTemplate"
Value="{DynamicResource local.DataGridValuesEditable}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
Upvotes: 0