在查看样本附加的属性和行为时,我已经看到了使用的混合物FrameworkPropertyMetadata,UIPropertyMetadata和PropertyMetadata.由于它们都构成了一个继承层次结构,我该如何选择使用哪一个?
对于那些使用纯MVVM的人来说,如何在不回复代码的情况下处理ComboBox SelectionChanged事件?
我尝试了例如AttachedBehaviors,但不支持Event ="SelectedChanged":
<ComboBox>
<ComboBoxItem Content="Test1">
<c:CommandBehaviorCollection.Behaviors>
<c:BehaviorBinding Event="SelectionChanged"
Command="{Binding SelectedChanged}"
CommandParameter="MainBorder123"/>
</c:CommandBehaviorCollection.Behaviors>
</ComboBoxItem>
<ComboBoxItem Content="Test2"/>
<ComboBoxItem Content="Test3"/>
</ComboBox>
Run Code Online (Sandbox Code Playgroud) 我使用Resharper 5.1代码分析很多次我从resharper得到一个评论
"通过匿名代表取消订阅"
#Part of Code
if (((bool)e.NewValue))
{
listView.PreviewTextInput += (o,args) =>
listView_PreviewTextInput(o,args,listView);
}
else
{
listView.PreviewTextInput -= (o, args) =>
listView_PreviewTextInput(o, args, listView);
}
Run Code Online (Sandbox Code Playgroud)
我怎么能纠正或优化这件事
在WPF和WinRT中,众所周知行为不能可靠地调用它们的Detach方法.避免内存泄漏的唯一方法是订阅AssociatedObject的Unloaded事件并取消挂起所有事件(示例).
到目前为止它的作用.
但我意识到(就像其他评论我链接的博客条目的人一样),以这种方式,卸载的行为永远不会再次附加.以MenuFlyout为例.如果有一个附加到MenuFlyoutItem的行为,则在关闭MenuFlyoutItem时将其卸载.如果再次打开菜单,则不会重新连接.
其他UserControl也会发生这种情况.当我在WinRT应用程序中从一个页面导航到另一个页面时,我"失去"行为,然后再次返回,尽管所有控件都重新创建.我没有看到如何在WinRT应用程序中使用它们,其中通过导航重新创建了许多控件.
有没有已知的解决方案?
我正在研究WPF MVVM应用程序.我注意到的是,我必须编写过多的样板代码来声明命令(通过WPF Team的MVVM Toolkit中的DelegateCommands),附加属性和附加行为.有没有可用的策略来减少我必须编写的样板代码的数量?
谢谢!
我知道我需要调用RemoveValueChanged,但我找不到一个可靠的地方来调用它.我知道可能没有一个.
我看起来需要找到一种不同的方法来监控更改,然后使用AddValueChanged添加一个处理程序.我正在寻找有关实现这一目标的最佳方法的建议.我已经看到了在PropertyMetadata中使用PropertyChangedCallback的建议,但是当我的TextBox和Adorner不是静态的时候我不确定如何做到这一点.此外,IsFocused属性不是在我的类中创建的DependencyProperty.
谢谢.
public sealed class WatermarkTextBoxBehavior
{
private readonly TextBox m_TextBox;
private TextBlockAdorner m_TextBlockAdorner;
private WatermarkTextBoxBehavior(TextBox textBox)
{
if (textBox == null)
throw new ArgumentNullException("textBox");
m_TextBox = textBox;
}
#region Behavior Internals
private static WatermarkTextBoxBehavior GetWatermarkTextBoxBehavior(DependencyObject obj)
{
return (WatermarkTextBoxBehavior)obj.GetValue(WatermarkTextBoxBehaviorProperty);
}
private static void SetWatermarkTextBoxBehavior(DependencyObject obj, WatermarkTextBoxBehavior value)
{
obj.SetValue(WatermarkTextBoxBehaviorProperty, value);
}
private static readonly DependencyProperty WatermarkTextBoxBehaviorProperty =
DependencyProperty.RegisterAttached("WatermarkTextBoxBehavior",
typeof(WatermarkTextBoxBehavior), typeof(WatermarkTextBoxBehavior), new UIPropertyMetadata(null));
public static bool GetEnableWatermark(TextBox obj)
{
return (bool)obj.GetValue(EnableWatermarkProperty);
}
public static void SetEnableWatermark(TextBox obj, bool value) …Run Code Online (Sandbox Code Playgroud) 一般来说,我仍然习惯于附加行为,并且看不出如何为一个人编写单元测试.
我在Sacha Barber的Cinch框架下面粘贴了一些代码,允许通过附加行为关闭窗口.有人能告诉我一个示例单元测试吗?
谢谢!
Berryl
#region Close
/// <summary>Dependency property which holds the ICommand for the Close event</summary>
public static readonly DependencyProperty CloseProperty =
DependencyProperty.RegisterAttached("Close",
typeof(ICommand), typeof(Lifetime),
new UIPropertyMetadata(null, OnCloseEventInfoChanged));
/// <summary>Attached Property getter to retrieve the CloseProperty ICommand</summary>
public static ICommand GetClose(DependencyObject source)
{
return (ICommand)source.GetValue(CloseProperty);
}
/// <summary>Attached Property setter to change the CloseProperty ICommand</summary>
public static void SetClose(DependencyObject source, ICommand command)
{
source.SetValue(CloseProperty, command);
}
/// <summary>This is the property changed handler for the Close property.</summary>
private …Run Code Online (Sandbox Code Playgroud) 我目前正在将我创建的一些附加行为迁移到Blend Behaviors,以便它们支持Expression Blend中的拖放.我注意到Blend行为的作者倾向于将行为属性定义为依赖属性.
我创建了一个行为,TiltBehaviour它公开了一个TiltFactordouble类型的公共依赖属性.在Expression Blend中我可以设置此属性的值,但是,添加"数据绑定..."的选项显示为灰色:

我还注意到Behaviors扩展DependencyObject,因此它们没有a DataContext,因此无法继承DataContext它们所附加的元素.这对我来说真是个弱点!
所以,底线是,如果我无法在Blend中设置绑定到我的行为依赖属性,并且它没有继承DataContext,为什么还要使用依赖属性呢?我可以使用CLR属性.
我的目标是为FlowDocumentScrollViewer创建可重用的附加行为,以便每当FlowDocument更新(附加)时,查看器自动滚动到末尾.
到目前为止的问题
我意识到那些可能是3个独立的问题(也就是问题).但是它们彼此依赖,并且我尝试了这种行为的整体设计.我问这是一个单一的问题,以防我以错误的方式解决这个问题.如果我是,那么正确的方法是什么?
/// Attached Dependency Properties not shown here:
/// bool Enabled
/// DependencyProperty DocumentProperty
/// TextRange MonitoredRange
/// ScrollViewer ScrollViewer
public static void OnEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d == null || System.ComponentModel.DesignerProperties.GetIsInDesignMode(d))
return;
DependencyProperty documentProperty = null;
ScrollViewer scrollViewer = null;
if (e.NewValue is bool && (bool)e.NewValue)
{
// Using reflection so that this will work with similar types.
FieldInfo documentFieldInfo = d.GetType().GetFields().FirstOrDefault((m) => m.Name == "DocumentProperty");
documentProperty = documentFieldInfo.GetValue(d) as DependencyProperty;
// …Run Code Online (Sandbox Code Playgroud) 我一直在尝试在wpf窗口上实现一个行为,因此我在当前的解决方案中添加了对System.Winodws.Interactivity的引用,然后编写了所需的行为.但是为了应用这种行为,我必须在Windows XAML中编写类似的东西.
<Window x:Class="WpfApplication5.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:behav ="clr-namespace:WpfApplication5"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity;assembly=System.Windows.Interactivity">
<Window.Resources>
<i:Interaction.Behaviors>
<behav:DialogIconRemoveBehavior></behav:DialogIconRemoveBehavior>
</i:Interaction.Behaviors>
</Window.Resources>
<Grid>
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
但这不是有效的标签,因为我可能必须添加对System.Windows.Interactivity的任何其他程序集的引用,所以,请建议我在XAML中使用标签时还需要做些什么
wpf ×10
c# ×3
mvvm ×3
xaml ×2
blend ×1
c#-4.0 ×1
events ×1
memory-leaks ×1
silverlight ×1
unit-testing ×1