【发布时间】:2023-04-01 23:19:02
【问题描述】:
我有这个绑定到ObservableCollection 的ComboBox:
<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>
我有这个ContextMenu,我正在努力实施(正在进行中):
<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>
暂时忽略移除特殊事件。
以下是两个相关的命令:
_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);
并且,这样ContextMenu 将在下次正确设置菜单状态:
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;
所以我的上下文菜单现在总是匹配当前组合菜单项的状态。
但是当我将一个组合项设置为以前不是一个的事件时,组合项不会更新并添加图像。我决定将 ItemSource 也设置为 UpdateTriggerSource=PropertyChanged。
然后,我调整了我的监听事件处理程序:
private void Meeting_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
OnPropertyChanged(e.PropertyName);
if (e.PropertyName == "IsSpecialEvent" || e.PropertyName == "IsCircuitVisit")
OnPropertyChanged("Meetings");
}
但这不正常。该列表现在用图标显示它,但不显示当前项目本身。
我错过了什么步骤?
为了看到它,我必须选择另一个菜单项,然后再回到它。
谢谢。
更新
我更改了我的两个模型属性:
[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");
}
}
他们现在也触发了 DisplayBellImage,一切看起来都很好。但我确实需要按照我的方式更新 ItemSource,对吧?
【问题讨论】:
-
钟形图像的可见性似乎是由名为
DisplayBellImage的属性值驱动的。我没有看到你改变过该财产的价值或为它提高PropertyChanged。 -
@EdPlunkett 不错! :) 我已经更新了这个问题。谢谢。
-
您似乎正在为您的 UI 使用主题。从组合框中删除主题以检查您是否可以看到您的图标。我个人的嫌疑人是你的主题。
-
安德鲁,“一切似乎都很好”,你是说你的问题已经解决了吗?
-
@EdPlunkett ViewModel 正在监听它对源所做的更改(具有讽刺意味的是)。所以它可以通知视图。听起来我需要做的就是不听,只做选择性的 onpropertychanged 调用。