Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从静态资源中添加样式设置器作为附加行为_C#_Wpf_Visual Studio 2013_Attached Properties - Fatal编程技术网

C# 如何从静态资源中添加样式设置器作为附加行为

C# 如何从静态资源中添加样式设置器作为附加行为,c#,wpf,visual-studio-2013,attached-properties,C#,Wpf,Visual Studio 2013,Attached Properties,我使用附加的依赖属性创建了一个行为,将一个公共的SetterBaseCollection提供给不同的相关样式 该行为只是管理附加的主机属性上的集合,以便将其与视图中的静态资源对齐。我刚刚将其连接到AP PropertyChangedCallback,这对于我拥有的另一种行为很好,即填充CommandBindings,但在将其应用于样式设置器时抛出 错误是 System.Windows.Markup.XamlParseException occurred _HResult=-214623308

我使用附加的依赖属性创建了一个行为,将一个公共的
SetterBaseCollection
提供给不同的相关样式

该行为只是管理附加的主机属性上的集合,以便将其与视图中的静态资源对齐。我刚刚将其连接到AP PropertyChangedCallback,这对于我拥有的另一种行为很好,即填充CommandBindings,但在将其应用于样式设置器时抛出

错误是

System.Windows.Markup.XamlParseException occurred
  _HResult=-2146233087
  _message='Set property 'System.Windows.EventSetter.Event' threw an exception.' Line number '12' and line position '26'.
  HResult=-2146233087
  IsTransient=false
  Message='Set property 'System.Windows.EventSetter.Event' threw an exception.' Line number '12' and line position '26'.
  Source=PresentationFramework
  LineNumber=12
  LinePosition=26
  StackTrace:
       at System.Windows.Markup.XamlReader.RewrapException(Exception e, IXamlLineInfo lineInfo, Uri baseUri)
  InnerException: System.ArgumentNullException
       _HResult=-2147467261
       _message=Value cannot be null.
       HResult=-2147467261
       IsTransient=false
       Message=Value cannot be null.
Parameter name: value
       Source=PresentationFramework
       ParamName=value
       StackTrace:
            at System.Windows.EventSetter.set_Event(RoutedEvent value)
       InnerException: 
在错误发生之前不会调用行为代码,因此它是xaml中的一部分

景色 行为课
公共静态只读DependencyProperty StyleSettersProperty=
DependencyProperty.RegisterAttached(
“样式设置器”,字体(SetterBaseCollection),
类型(行为),
新属性元数据(默认值(SetterBaseCollection),
(t,a)=>UpdateCollection
(框架元素)t.风格,a,“Setters”);
公共静态void SetStyleSetters(DependencyObject元素,
SetterBaseCollection值)
{
SetValue(StyleSettersProperty,value);
}
公共静态SetterBaseCollection GetStyleSetters(
DependencyObject元素)
{
返回(SetterBaseCollection)元素
.GetValue(StyleSettersProperty);
}
#端区
私有静态void UpdateCollection(
对象目标,DependencyPropertyChangedEventArgs参数,
字符串targetCollection)
其中t集合:类,IList
托斯特:在哪里上课
{
var host=目标为THost;
if(host==null)返回;
var collection=typeof(THost).GetProperty(targetCollection)
.GetValue(主机)作为IList;
if(collection==null)返回;
var oldValue=args.oldValue作为TCollection;
if(oldValue!=null)
{
foreach(oldValue中的var成员)
{
集合。移除(成员);
}
}
尝试
{
var newValue=args.newValue作为TCollection;
if(newValue!=null)
{
foreach(newValue中的var成员)
{
集合。添加(成员);
}
}
}
捕获(例外e)
{
WriteLine(“{0}在UpdateCollection中”);
}
}
StaticResource的值始终为空。

每次在按钮上设置属性并将按钮作为第一个参数传递时,都会点击OnPropertyChanged回调。

样式不是DependencyObject,因此无法在样式上设置样式设置器附加属性。

样式不是DependencyObject,因此无法在样式上设置样式设置器附加属性一种风格。@mm8啊,当然可以。谢谢,还有别的办法吗?我尝试了一种不同的方法来避免这个问题,但仍然无法让它工作。你有什么看法吗?我想没有。不能将触发器的Setters属性直接设置为在XAML中定义为资源的SetterBaseCollection对象,因为该属性是只读的:它是只读的,但其成员不是。我应该能够像我在代码中一样添加到集合中,不是吗?你不能将setters添加到按钮的样式中,因为它是密封的。啊,好的。是的,我在源代码中看到:
IsSealed
。我想我已经击中了我的WPF WTF密封(原文如此)。我不再打扰你了,读一读我的博客。干杯
<Window.Resources>

    <Thickness x:Key="ButtonMargin">6</Thickness>

    <SetterBaseCollection x:Key="ButtonStyleSetters">
        <EventSetter Event="ButtonBase.Click" Handler="StyleClick" />
        <Setter Property="FrameworkElement.Height" Value="30" />
        <Setter Property="FrameworkElement.Margin" Value="6" />
    </SetterBaseCollection>

    <Style TargetType="{x:Type Button}" 
           b:Behaviours.StyleSetters="{StaticResource ButtonStyleSetters}" />
    <Style TargetType="{x:Type ToggleButton}"
           b:Behaviours.StyleSetters="{StaticResource ButtonStyleSetters}" />
    <Style TargetType="{x:Type CheckBox}">
        <EventSetter Event="Click" Handler="StyleClick" />
    </Style>
    <Style TargetType="{x:Type b:MultiCommandButton}"
           b:Behaviours.StyleSetters="{StaticResource ButtonStyleSetters}" />

    <Style TargetType="UniformGrid">
        <Setter Property="Columns" Value="2" />
    </Style>

    <CommandBindingCollection x:Key="OutputToggleReceiveAll">
        <b:OutputToggleBind />
        <b:OutputToggleEnabledBind />
    </CommandBindingCollection>

</Window.Resources>
public static class Behaviours
{
    #region AP CommandReceivers

    public static readonly DependencyProperty CommandReceiversProperty =
        DependencyProperty.RegisterAttached(
            "CommandReceivers", typeof(CommandBindingCollection),
            typeof(Behaviours),
            new PropertyMetadata(default(CommandBindingCollection),
                (t, a) => UpdateCollection<CommandBindingCollection, UIElement>
                    (t, a, "CommandBindings")));

    public static void SetCommandReceivers(DependencyObject element,
        CommandBindingCollection value)
    {
        element.SetValue(CommandReceiversProperty, value);
    }

    public static CommandBindingCollection GetCommandReceivers(
        DependencyObject element)
    {
        return (CommandBindingCollection) element
            .GetValue(CommandReceiversProperty);
    }

    #endregion

    #region AP StyleSetters

    public static readonly DependencyProperty StyleSettersProperty =
        DependencyProperty.RegisterAttached(
            "StyleSetters", typeof(SetterBaseCollection),
            typeof(Behaviours),
            new PropertyMetadata(default(SetterBaseCollection),
                (t, a) => UpdateCollection<SetterBaseCollection, UIElement>
                    (t, a, "Setters")));

    public static void SetStyleSetters (DependencyObject element,
        SetterBaseCollection value)
    {
        element.SetValue(StyleSettersProperty, value);
    }

    public static SetterBaseCollection GetStyleSetters (
        DependencyObject element)
    {
        return (SetterBaseCollection)element
            .GetValue(StyleSettersProperty);
    }

    #endregion

    private static void UpdateCollection<TCollection, THost> (
        DependencyObject target, DependencyPropertyChangedEventArgs args, 
        string targetCollection)
        where TCollection : IList
        where THost : class
    {
        var host = target as THost;
        if (host == null) return;

        var collection = typeof(THost).GetProperty(targetCollection)
            .GetValue(host) as IList;
        if (collection == null) return;

        if (args.OldValue != null)
        {
            foreach (var member in
                (TCollection) args.OldValue)
            {
                collection.Remove(member);
            }
        }
        if (args.NewValue != null)
        {
            foreach (var member in
                (TCollection) args.NewValue)
            {
                collection.Add(member);
            }
        }
    }
}
<Window.Resources>

    <SetterBaseCollection x:Key="ButtonStyleSetters">
        <EventSetter Event="ButtonBase.Click" Handler="StyleClick" />
        <Setter Property="FrameworkElement.Height" Value="30" />
        <Setter Property="FrameworkElement.Margin" Value="6" />
    </SetterBaseCollection>

    <Style TargetType="{x:Type Button}" >
        <Setter Property="local:Behaviours.StyleSetters" 
                Value="{StaticResource ButtonStyleSetters}"/>
    </Style>

</Window.Resources>
public static readonly DependencyProperty StyleSettersProperty =
    DependencyProperty.RegisterAttached(
        "StyleSetters", typeof(SetterBaseCollection),
        typeof(Behaviours),
        new PropertyMetadata(default(SetterBaseCollection),
            (t, a) => UpdateCollection<SetterBaseCollection, Style>
                (((FrameworkElement)t).Style, a, "Setters")));

public static void SetStyleSetters (DependencyObject element,
    SetterBaseCollection value)
{
    element.SetValue(StyleSettersProperty, value);
}

public static SetterBaseCollection GetStyleSetters (
    DependencyObject element)
{
    return (SetterBaseCollection)element
        .GetValue(StyleSettersProperty);
}

#endregion

private static void UpdateCollection<TCollection, THost> (
    object target, DependencyPropertyChangedEventArgs args, 
    string targetCollection)
    where TCollection : class, IList
    where THost : class
{
    var host = target as THost;
    if (host == null) return;

    var collection = typeof(THost).GetProperty(targetCollection)
        .GetValue(host) as IList;
    if (collection == null) return;

    var oldValue = args.OldValue as TCollection;
    if (oldValue != null)
    {
        foreach (var member in oldValue)
        {
            collection.Remove(member);
        }
    }
    try
    {
        var newValue = args.NewValue as TCollection;
        if (newValue != null)
        {
            foreach (var member in newValue)
            {
                collection.Add(member);
            }
        }

    }
    catch (Exception e)
    {
        Debug.WriteLine("{0} in UpdateCollection<TCollection, THost>");
    }
}