Reputation: 19097
I have this ComboBox
that is bound to an ObservableCollection
:
<ComboBox x:Name="comboMeetingWeek" ItemsSource="{Binding Meetings}"
SelectedItem="{Binding Meeting, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="Images/Bell.png" Margin="0,0,5,0"
Visibility="{Binding DisplayBellImage, Converter={StaticResource BoolToHiddenConverter}}" Stretch="None"/>
<TextBlock Text="{Binding DateMeetingAsText}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
And I have this ContextMenu
that I am working on implementing (a work in progress):
<Image Grid.Column="1" HorizontalAlignment="Right" Source="Images\event_time.png" Margin="2">
<Image.ContextMenu>
<ContextMenu>
<MenuItem Header="Set Special Event" Command="{Binding SetSpecialEventCommand, Mode=OneWay}"/>
<MenuItem Header="Edit Special Event" Command="{Binding EditSpecialEventCommand, Mode=OneWay}"/>
<MenuItem Header="Remove Special Event">
<MenuItem.Style>
<Style TargetType="MenuItem">
<Setter Property="IsEnabled" Value="False"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Meeting.IsSpecialEvent}" Value="True">
<Setter Property="IsEnabled" Value="True"/>
</DataTrigger>
</Style.Triggers>
</Style>
</MenuItem.Style>
</MenuItem>
</ContextMenu>
</Image.ContextMenu>
</Image>
Ignoring Remove Special Event for now.
Here are the two associated Commands:
_SetSpecialEventCommand = new DelegateCommand<string>(
(s) =>
{
SpecialEventWindow windowEvent = new SpecialEventWindow();
windowEvent.DataContext = this;
windowEvent.ShowDialog();
if (windowEvent.DialogResult.HasValue && windowEvent.DialogResult.Value)
_Meeting.IsSpecialEvent = true;
},
(s) => !_Meeting.IsSpecialEvent);
_EditSpecialEventCommand = new DelegateCommand<string>(
(s) =>
{
SpecialEventWindow windowEvent = new SpecialEventWindow();
windowEvent.DataContext = this;
windowEvent.ShowDialog();
if (windowEvent.DialogResult.HasValue && windowEvent.DialogResult.Value)
_Meeting.IsSpecialEvent = true;
else
_Meeting.IsSpecialEvent = false;
},
(s) => _Meeting.IsSpecialEvent);
And, so that the ContextMenu
will correctly set the menu states the next time around it does:
public Data.MeetingInfo.Meeting Meeting
{
get { return _Meeting; }
set
{
// Has the existing meeting object changed at all?
if(_Meeting != null && _Meeting.IsDirty)
{
// Yes, so save it
_Model.Serialize();
_Meeting.MarkClean();
}
// Now we can update to new value
if (value != null)
{
_Meeting = value;
OnPropertyChanged("Meeting");
_SetSpecialEventCommand.RaiseCanExecuteChanged();
_EditSpecialEventCommand.RaiseCanExecuteChanged();
}
}
}
private Data.MeetingInfo.Meeting _Meeting;
So my context menu now always matches the state of the current combo menu item.
But when I set a combo item as an event when it was not one before, the combo item does not update and add the image. I decided to set the ItemSource to also have an UpdateTriggerSource=PropertyChanged
.
Then, I adjusted my listening event handler:
private void Meeting_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
OnPropertyChanged(e.PropertyName);
if (e.PropertyName == "IsSpecialEvent" || e.PropertyName == "IsCircuitVisit")
OnPropertyChanged("Meetings");
}
But that is not working right. The list shows it now with an icon but not the current item itself.
What step am I missing?
In order to see it I must pick another menu item and then come back to it.
Thank you.
I changed my two Model properties:
[XmlIgnore]
public bool IsSpecialEvent
{
get { return _SpecialEvent.Event; }
set
{
_SpecialEvent.Event = value;
MarkDirty();
OnPropertyChanged("IsSpecialEvent");
OnPropertyChanged("DisplayBellImage");
}
}
[XmlIgnore]
public bool IsCircuitVisit
{
get { return _SpecialEvent.CircuitVisit; }
set
{
_SpecialEvent.CircuitVisit = value;
MarkDirty();
OnPropertyChanged("IsCircuitVisit");
OnPropertyChanged("DisplayBellImage");
}
}
They now also fire the DisplayBellImage and all seems good. But I did need to update the ItemSource the way that I did, right?
Upvotes: 2
Views: 51
Reputation: 37059
The visibility of the bell image seems to be driven by the value of a property called DisplayBellImage
. I don't see you ever changing the value of that property, or raising PropertyChanged
for it. You should be calling OnPropertyChanged("DisplayBellImage");
every time the value of DisplayBellImage
changes.
Upvotes: 1