我有一个下拉框,可以更改屏幕上显示的内容。如果IsDirty变量为true,我希望弹出窗口通知用户如果尝试更改下拉列表,则存在未保存的更改。
下拉列表绑定到属性,我尝试将消息框放入属性集合中的效果不佳。似乎每当我试图拦截机会并修改它时,结果是属性上的设置再次触发。
我尝试了一些我在网上找到的没有运气的解决方案,有人有任何消化吗?
我最近的尝试是附加一个行为,但它有多次触发相同的问题,并且值仍然发生了变化。
我正在使用.net 4.5
public class CancellableSelectionBehavior : Behavior<ComboBox>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.SelectionChanged += OnSelectionChanged;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.SelectionChanged -= OnSelectionChanged;
}
#region Properties
#region IsDirtyCheck
public static readonly DependencyProperty IsDirtyCheckProperty =
DependencyProperty.Register(
Reflection.GetPropertyName<CancellableSelectionBehavior>(m => m.IsDirtyCheck),
typeof(bool),
typeof(CancellableSelectionBehavior));
public bool IsDirtyCheck
{
get { return (bool)GetValue(IsDirtyCheckProperty); }
set { SetValue(IsDirtyCheckProperty, value); }
}
#endregion
#region Selected Value
public static readonly DependencyProperty SelectedValueProperty =
DependencyProperty.Register(Reflection.GetPropertyName<CancellableSelectionBehavior>(m => m.SelectedValue),
typeof(object), typeof(CancellableSelectionBehavior),
new FrameworkPropertyMetadata(null,
FrameworkPropertyMetadataOptions
.BindsTwoWayByDefault, OnSelectedItemChanged));
public object SelectedValue
{
get { return GetValue(SelectedValueProperty); }
set { SetValue(SelectedValueProperty, value); }
}
#endregion
#endregion
private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var behavior = (CancellableSelectionBehavior)d;
var selector = behavior.AssociatedObject;
if (e.OldValue != null)
{
if (e.OldValue != e.NewValue)
{
if (behavior.IsDirtyCheck)
{
string message = string.Format(UserMessages.UnSavedFaultPlygon, Environment.NewLine);
if (ServiceLocationContext.ServiceFinder.GetService<IMessageBox>()
.Show(new MessageDialogOptions(message,
UserMessages
.FaultPlygons,
MessageDialogIcon
.Exclamation,
MessageDialogButtons
.YesNo)) == MessageDialogResult.Yes)
{
selector.SelectedValue = e.NewValue;
}
else
{
selector.SelectedValue = e.OldValue;
}
}
else
{
selector.SelectedValue = e.NewValue;
}
}
}
}
/// <summary>
/// Called when the associated selector's selection is changed.
/// Tries to assign it to the <see cref="SelectedItem"/> property.
/// If it fails, updates the selector's with <see cref="SelectedItem"/> property's current value.
/// </summary>
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if ((e.AddedItems == null || e.AddedItems.Count == 0)) return;
SelectedValue = AssociatedObject.SelectedValue;
}
}
<ribbonDropDown:RibbonDropDownListView
Label="{Binding Path=MapModel.SelectedPostingItemName}"
Image="{Binding Path=LargeImageSource, ElementName=_postingTypeMenuButton}"
Width="100"
ItemsSource="{Binding Path=MapModel.PostingHorizonItems}"
SelectedValuePath="Key"
Visibility="{Binding Path=MapModel.SelectedTypeKey, Converter={StaticResource EnumMatchToVisibilityConverter}, ConverterParameter={x:Static map2:MapPostingType.Horizon}}"
ToolTip="{Binding Path=MapModel.SelectedPostingItemDescription}">
<i:Interaction.Behaviors>
<common:CancellableSelectionBehavior IsDirtyCheck="{Binding Path=MapControlViewModel.IsFaultPolygonDirty}"
SelectedValue="{Binding Path=MapModel.SelectedHorizonPostingItem}"/>
</i:Interaction.Behaviors>
答案 0 :(得分:0)
我可能会过分简化答案,但我相信问题是您正在捕获onselectionchanged事件,然后更改该代码块内的选择。
行为看起来很整洁,但我认为你必须把它挂钩而不是基于这种事件。
我会像这样解决问题。 (如果您认为可能会抛出异常,也许可以尝试最终重新附加事件。)
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if ((e.AddedItems == null || e.AddedItems.Count == 0)) return;
AssociatedObject.SelectionChanged -= OnSelectionChanged;
SelectedValue = AssociatedObject.SelectedValue;
AssociatedObject.SelectionChanged += OnSelectionChanged;
}