스타일 설정 기에서 블렌드 비헤이비어를 추가하는 방법


88

Button에 대한 Blend 동작을 만들었습니다. 앱의 모든 버튼에 어떻게 설정할 수 있습니까?

<Button ...>
  <i:Interaction.Behaviors>
    <local:MyBehavior />
  </i:Interaction.Behaviors>
</Button>

그러나 내가 시도 할 때 :

<Style>
  <Setter Property="i:Interaction.Behaviors">
    <Setter.Value>
      <local:MyBehavior />
    </Setter.Value>
  </Setter>
</Style>

오류가 발생합니다

"Behaviors"속성에 액세스 할 수있는 setter가 없습니다.

답변:


76

나는 같은 문제가 있었고 해결책을 찾았습니다. 이 질문을 해결 한 후이 질문을 찾았고 내 솔루션이 Mark와 많은 공통점이 있음을 알았습니다. 그러나이 접근 방식은 약간 다릅니다.

주요 문제는 동작과 트리거가 특정 개체와 연결되어 있으므로 여러 다른 연결된 개체에 대해 동일한 동작 인스턴스를 사용할 수 없다는 것입니다. 동작을 정의 할 때 인라인 XAML은이 일대일 관계를 적용합니다. 그러나 스타일에서 비헤이비어를 설정하려고하면 스타일이 적용되는 모든 객체에 대해 재사용 될 수 있으며 기본 비헤이비어 클래스에서 예외가 발생합니다. 사실 저자들은 우리가이 작업을 시도하는 것을 막기 위해 상당한 노력을 기울였습니다.

첫 번째 문제는 생성자가 내부이기 때문에 동작 setter 값을 구성 할 수도 없다는 것입니다. 그래서 우리는 우리 자신의 행동과 트리거 컬렉션 클래스가 필요합니다.

다음 문제는 동작 및 트리거 연결된 속성에 setter가 없으므로 인라인 XAML로만 추가 할 수 있다는 것입니다. 이 문제는 기본 동작을 조작하고 속성을 트리거하는 자체 연결된 속성으로 해결합니다.

세 번째 문제는 비헤이비어 컬렉션이 단일 스타일 대상에만 적합하다는 것입니다. 이 문제 x:Shared="False"는 참조 할 때마다 리소스의 새 복사본을 만드는 거의 사용되지 않는 XAML 기능 을 활용하여 해결합니다 .

마지막 문제는 동작과 트리거가 다른 스타일 설정자와 같지 않다는 것입니다. 우리는 이전 행동을 새로운 행동으로 바꾸고 싶지 않습니다. 왜냐하면 그들은 매우 다른 일을 할 수 있기 때문입니다. 따라서 일단 동작을 추가 한 후에는 제거 할 수 없다는 것을 받아 들인다면 (현재 동작이 작동하는 방식입니다), 동작과 트리거가 추가되어야하며 연결된 속성에 의해 처리 될 수 있다는 결론을 내릴 수 있습니다.

다음은이 접근 방식을 사용하는 샘플입니다.

<Grid>
    <Grid.Resources>
        <sys:String x:Key="stringResource1">stringResource1</sys:String>
        <local:Triggers x:Key="debugTriggers" x:Shared="False">
            <i:EventTrigger EventName="MouseLeftButtonDown">
                <local:DebugAction Message="DataContext: {0}" MessageParameter="{Binding}"/>
                <local:DebugAction Message="ElementName: {0}" MessageParameter="{Binding Text, ElementName=textBlock2}"/>
                <local:DebugAction Message="Mentor: {0}" MessageParameter="{Binding Text, RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}}"/>
            </i:EventTrigger>
        </local:Triggers>
        <Style x:Key="debugBehavior" TargetType="FrameworkElement">
            <Setter Property="local:SupplementaryInteraction.Triggers" Value="{StaticResource debugTriggers}"/>
        </Style>
    </Grid.Resources>
    <StackPanel DataContext="{StaticResource stringResource1}">
        <TextBlock Name="textBlock1" Text="textBlock1" Style="{StaticResource debugBehavior}"/>
        <TextBlock Name="textBlock2" Text="textBlock2" Style="{StaticResource debugBehavior}"/>
        <TextBlock Name="textBlock3" Text="textBlock3" Style="{StaticResource debugBehavior}"/>
    </StackPanel>
</Grid>

이 예제에서는 트리거를 사용하지만 동작은 동일한 방식으로 작동합니다. 이 예에서는 다음을 보여줍니다.

  • 스타일을 여러 텍스트 블록에 적용 할 수 있습니다.
  • 여러 유형의 데이터 바인딩이 모두 올바르게 작동합니다.
  • 출력 창에 텍스트를 생성하는 디버그 동작

다음은 우리의 DebugAction. 더 적절하게는 그것은 행동이지만 언어 남용을 통해 우리는 행동, 방아쇠 및 행동을 "행동"이라고 부릅니다.

public class DebugAction : TriggerAction<DependencyObject>
{
    public string Message
    {
        get { return (string)GetValue(MessageProperty); }
        set { SetValue(MessageProperty, value); }
    }

    public static readonly DependencyProperty MessageProperty =
        DependencyProperty.Register("Message", typeof(string), typeof(DebugAction), new UIPropertyMetadata(""));

    public object MessageParameter
    {
        get { return (object)GetValue(MessageParameterProperty); }
        set { SetValue(MessageParameterProperty, value); }
    }

    public static readonly DependencyProperty MessageParameterProperty =
        DependencyProperty.Register("MessageParameter", typeof(object), typeof(DebugAction), new UIPropertyMetadata(null));

    protected override void Invoke(object parameter)
    {
        Debug.WriteLine(Message, MessageParameter, AssociatedObject, parameter);
    }
}

마지막으로,이 모든 것이 작동하도록 컬렉션과 연결된 속성이 있습니다. 와 유사하게 Interaction.Behaviors,이 속성을 SupplementaryInteraction.Behaviors설정하면 Interaction.Behaviors트리거에 대한 동작을 추가하게되므로 대상 속성이 호출 됩니다.

public class Behaviors : List<Behavior>
{
}

public class Triggers : List<TriggerBase>
{
}

public static class SupplementaryInteraction
{
    public static Behaviors GetBehaviors(DependencyObject obj)
    {
        return (Behaviors)obj.GetValue(BehaviorsProperty);
    }

    public static void SetBehaviors(DependencyObject obj, Behaviors value)
    {
        obj.SetValue(BehaviorsProperty, value);
    }

    public static readonly DependencyProperty BehaviorsProperty =
        DependencyProperty.RegisterAttached("Behaviors", typeof(Behaviors), typeof(SupplementaryInteraction), new UIPropertyMetadata(null, OnPropertyBehaviorsChanged));

    private static void OnPropertyBehaviorsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var behaviors = Interaction.GetBehaviors(d);
        foreach (var behavior in e.NewValue as Behaviors) behaviors.Add(behavior);
    }

    public static Triggers GetTriggers(DependencyObject obj)
    {
        return (Triggers)obj.GetValue(TriggersProperty);
    }

    public static void SetTriggers(DependencyObject obj, Triggers value)
    {
        obj.SetValue(TriggersProperty, value);
    }

    public static readonly DependencyProperty TriggersProperty =
        DependencyProperty.RegisterAttached("Triggers", typeof(Triggers), typeof(SupplementaryInteraction), new UIPropertyMetadata(null, OnPropertyTriggersChanged));

    private static void OnPropertyTriggersChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var triggers = Interaction.GetTriggers(d);
        foreach (var trigger in e.NewValue as Triggers) triggers.Add(trigger);
    }
}

스타일을 통해 완전히 작동하는 동작과 트리거가 적용됩니다.


훌륭한 것들, 이것은 아름답게 작동합니다. 예를 들어 UserControl 리소스에 스타일을 넣으면 e.NewValue가 처음에는 null이 될 수 있음을 알았습니다 (사용 된 컨트롤에 따라 다를 수 있습니다-Infragistics XamDataTree의 XamDataTreeNodeControl에서 이것을 사용하고 있습니다). 그래서 OnPropertyTriggersChanged에 약간의 온 전성 검사를 추가했습니다. if (e.NewValue! = null)
MetalMikester 2011

암시 적 스타일 에서 Setter를 적용 할 때이 접근 방식에 문제가있는 사람이 있습니까? 비암 시적 스타일 (키가있는 스타일)에서 제대로 작동하도록했지만 암시 적 스타일이면 순환 참조 예외가 발생합니다.
Jason Frank

1
니스 솔루션,하지만 불행히도 그것을하지 WinRT에서하지 작업, X 때문에 : 공유가이 플랫폼에 존재하지 않는 ...
토마스 레베

1
이 솔루션이 작동하는지 확인할 수 있습니다. 공유해 주셔서 대단히 감사합니다. 나는 아직 암묵적인 스타일로 시도하지 않았습니다.
Golvellius 2013 년

2
@Jason Frank, 감사합니다. 다른 사람에 대한 참조처럼 ... 두 가지 경우 모두에서 작동하도록 만들었습니다 : 암시 적 및 명시 적. 사실 나는 다른 사람들을 돕기 위해 내 모든 코드를 어디에 두 었는지 질문하지만 누군가 내 질문이 중복되었다고 추정합니다. 나는 내가 찾은 모든 것을주는 내 질문에 답할 수 없다. 꽤 좋은 것을 발견 한 것 같아요. :-( ... 나는 그것이 너무 자주 그 행동이 유용한 정보를 다른 사용자가 박탈하기 때문에 발생하지 않습니다 바랍니다.
에릭 Ouellet

27

답변과이 훌륭한 기사 Blend Behaviors in Styles를 요약하면 다음과 같은 짧고 편리한 솔루션에 도달했습니다.

나는 어떤 행동으로도 상속 될 수있는 제네릭 클래스를 만들었다.

public class AttachableForStyleBehavior<TComponent, TBehavior> : Behavior<TComponent>
        where TComponent : System.Windows.DependencyObject
        where TBehavior : AttachableForStyleBehavior<TComponent, TBehavior> , new ()
    {
        public static DependencyProperty IsEnabledForStyleProperty =
            DependencyProperty.RegisterAttached("IsEnabledForStyle", typeof(bool),
            typeof(AttachableForStyleBehavior<TComponent, TBehavior>), new FrameworkPropertyMetadata(false, OnIsEnabledForStyleChanged)); 

        public bool IsEnabledForStyle
        {
            get { return (bool)GetValue(IsEnabledForStyleProperty); }
            set { SetValue(IsEnabledForStyleProperty, value); }
        }

        private static void OnIsEnabledForStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            UIElement uie = d as UIElement;

            if (uie != null)
            {
                var behColl = Interaction.GetBehaviors(uie);
                var existingBehavior = behColl.FirstOrDefault(b => b.GetType() ==
                      typeof(TBehavior)) as TBehavior;

                if ((bool)e.NewValue == false && existingBehavior != null)
                {
                    behColl.Remove(existingBehavior);
                }

                else if ((bool)e.NewValue == true && existingBehavior == null)
                {
                    behColl.Add(new TBehavior());
                }    
            }
        }
    }

따라서 다음과 같은 많은 구성 요소와 함께 간단히 재사용 할 수 있습니다.

public class ComboBoxBehaviour : AttachableForStyleBehavior<ComboBox, ComboBoxBehaviour>
    { ... }

그리고 선언하기에 충분한 XAML에서 :

 <Style TargetType="ComboBox">
            <Setter Property="behaviours:ComboBoxBehaviour.IsEnabledForStyle" Value="True"/>

따라서 기본적으로 AttachableForStyleBehavior 클래스는 xaml을 만들어 각 구성 요소의 동작 인스턴스를 스타일로 등록합니다. 자세한 내용은 링크를 참조하십시오.


매력처럼 작동합니다! 내 Scrollingbehavior를 결합하면 부모 Datagrid를 스크롤하지 않는 Inner RowDetailsTemplate-Datagrids를 제거했습니다.
Philipp Michalski 2015

기꺼이 도와) = 즐길
로마 Borodov

1
Behavior에서 종속성 속성을 사용한 데이터 바인딩은 어떻습니까?
JobaDiniz

개인적으로 사용자에게 연락하거나 부정적인 피드백으로 편집을 거부하는 방법을 모르겠습니다. @Der_Meister 및 기타 편집자 여러분, 편집하기 전에 코드를주의 깊게 읽어 보시기 바랍니다. 다른 사용자와 내 평판에도 영향을 미칠 수 있습니다. 이 경우 IsEnabledForStyle 속성을 제거하고이를 정적 메서드로 지속적으로 대체하면이 질문의 요점 인 xaml에서 속성에 바인딩 할 가능성이 없어집니다. 끝까지 코드를 읽지 않은 것 같습니다. Saddly 대단한 마이너스로 편집을 거부 할 수 없으니 앞으로도 조심해주세요.
Roma Borodov 2018

1
@RomaBorodov, 모든 것이 XAML에서 작동합니다. 연결된 속성을 정의하는 올바른 방법입니다 (종속 속성과 다름). 설명서 참조 : docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/…
Der_Meister

19

1. 첨부 속성 생성

public static class DataGridCellAttachedProperties
{
    //Register new attached property
    public static readonly DependencyProperty IsSingleClickEditModeProperty =
        DependencyProperty.RegisterAttached("IsSingleClickEditMode", typeof(bool), typeof(DataGridCellAttachedProperties), new UIPropertyMetadata(false, OnPropertyIsSingleClickEditModeChanged));

    private static void OnPropertyIsSingleClickEditModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var dataGridCell = d as DataGridCell;
        if (dataGridCell == null)
            return;

        var isSingleEditMode = GetIsSingleClickEditMode(d);
        var behaviors =  Interaction.GetBehaviors(d);
        var singleClickEditBehavior = behaviors.SingleOrDefault(x => x is SingleClickEditDataGridCellBehavior);

        if (singleClickEditBehavior != null && !isSingleEditMode)
            behaviors.Remove(singleClickEditBehavior);
        else if (singleClickEditBehavior == null && isSingleEditMode)
        {
            singleClickEditBehavior = new SingleClickEditDataGridCellBehavior();
            behaviors.Add(singleClickEditBehavior);
        }
    }

    public static bool GetIsSingleClickEditMode(DependencyObject obj)
    {
        return (bool) obj.GetValue(IsSingleClickEditModeProperty);
    }

    public static void SetIsSingleClickEditMode(DependencyObject obj, bool value)
    {
        obj.SetValue(IsSingleClickEditModeProperty, value);
    }
}

2. 행동 생성

public class SingleClickEditDataGridCellBehavior:Behavior<DataGridCell>
        {
            protected override void OnAttached()
            {
                base.OnAttached();
                AssociatedObject.PreviewMouseLeftButtonDown += DataGridCellPreviewMouseLeftButtonDown;
            }

            protected override void OnDetaching()
            {
                base.OnDetaching();
                AssociatedObject.PreviewMouseLeftButtonDown += DataGridCellPreviewMouseLeftButtonDown;
            }

            void DataGridCellPreviewMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
            {
                 DataGridCell cell = sender as DataGridCell;
                if (cell != null && !cell.IsEditing && !cell.IsReadOnly)
                {
                    if (!cell.IsFocused)
                    {
                        cell.Focus();
                    }
                    DataGrid dataGrid = LogicalTreeWalker.FindParentOfType<DataGrid>(cell); //FindVisualParent<DataGrid>(cell);
                    if (dataGrid != null)
                    {
                        if (dataGrid.SelectionUnit != DataGridSelectionUnit.FullRow)
                        {
                            if (!cell.IsSelected)
                                cell.IsSelected = true;
                        }
                        else
                        {
                            DataGridRow row =  LogicalTreeWalker.FindParentOfType<DataGridRow>(cell); //FindVisualParent<DataGridRow>(cell);
                            if (row != null && !row.IsSelected)
                            {
                                row.IsSelected = true;
                            }
                        }
                    }
                }
            }    
        }

3. Style 생성 및 연결된 속성 설정

        <Style TargetType="{x:Type DataGridCell}">
            <Setter Property="Behaviors:DataGridCellAttachedProperties.IsSingleClickEditMode" Value="True"/>
        </Style>

스타일에서 DependencyProperty에 액세스하려고하면 IsSingleClickEditMode가 인식되지 않거나 액세스 할 수 없다고 표시됩니까?
Igor Meszaros

죄송합니다 나의 나쁜 ... 곧 내가 GetIsSingleClickEditMode 당신이 DependencyProperty.RegisterAttached에 전달 문자열과 일치해야 실현 주석으로
이고르 메스 자 로스

OnDetaching은 또 다른 이벤트 핸들러를 추가합니다.이 문제는 수정되어야합니다 (게시물을 편집 할 때 단일 문자를 수정할 수 없음 ...)
BalintPogatsa

11

모든 동작에 대해 연결된 속성을 생성하지 않으려는 또 다른 아이디어가 있습니다.

  1. 행동 생성자 인터페이스 :

    public interface IBehaviorCreator
    {
        Behavior Create();
    }
    
  2. 작은 도우미 컬렉션 :

    public class BehaviorCreatorCollection : Collection<IBehaviorCreator> { }
    
  3. 비헤이비어를 첨부하는 도우미 클래스 :

    public static class BehaviorInStyleAttacher
    {
        #region Attached Properties
    
        public static readonly DependencyProperty BehaviorsProperty =
            DependencyProperty.RegisterAttached(
                "Behaviors",
                typeof(BehaviorCreatorCollection),
                typeof(BehaviorInStyleAttacher),
                new UIPropertyMetadata(null, OnBehaviorsChanged));
    
        #endregion
    
        #region Getter and Setter of Attached Properties
    
        public static BehaviorCreatorCollection GetBehaviors(TreeView treeView)
        {
            return (BehaviorCreatorCollection)treeView.GetValue(BehaviorsProperty);
        }
    
        public static void SetBehaviors(
            TreeView treeView, BehaviorCreatorCollection value)
        {
            treeView.SetValue(BehaviorsProperty, value);
        }
    
        #endregion
    
        #region on property changed methods
    
        private static void OnBehaviorsChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
        {
            if (e.NewValue is BehaviorCreatorCollection == false)
                return;
    
            BehaviorCreatorCollection newBehaviorCollection = e.NewValue as BehaviorCreatorCollection;
    
            BehaviorCollection behaviorCollection = Interaction.GetBehaviors(depObj);
            behaviorCollection.Clear();
            foreach (IBehaviorCreator behavior in newBehaviorCollection)
            {
                behaviorCollection.Add(behavior.Create());
            }
        }
    
        #endregion
    }
    
  4. 이제 IBehaviorCreator를 구현하는 동작 :

    public class SingleClickEditDataGridCellBehavior:Behavior<DataGridCell>, IBehaviorCreator
    {
        //some code ...
    
        public Behavior Create()
        {
            // here of course you can also set properties if required
            return new SingleClickEditDataGridCellBehavior();
        }
    }
    
  5. 이제 xaml에서 사용하십시오.

    <Style TargetType="{x:Type DataGridCell}">
      <Setter Property="helper:BehaviorInStyleAttacher.Behaviors" >
        <Setter.Value>
          <helper:BehaviorCreatorCollection>
            <behaviors:SingleClickEditDataGridCellBehavior/>
          </helper:BehaviorCreatorCollection>
        </Setter.Value>
      </Setter>
    </Style>
    

5

원작은 찾을 수 없지만 효과를 재현 할 수있었습니다.

#region Attached Properties Boilerplate

    public static readonly DependencyProperty IsActiveProperty = DependencyProperty.RegisterAttached("IsActive", typeof(bool), typeof(ScrollIntoViewBehavior), new PropertyMetadata(false, OnIsActiveChanged));

    public static bool GetIsActive(FrameworkElement control)
    {
        return (bool)control.GetValue(IsActiveProperty);
    }

    public static void SetIsActive(
      FrameworkElement control, bool value)
    {
        control.SetValue(IsActiveProperty, value);
    }

    private static void OnIsActiveChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var behaviors = Interaction.GetBehaviors(d);
        var newValue = (bool)e.NewValue;

        if (newValue)
        {
            //add the behavior if we don't already have one
            if (!behaviors.OfType<ScrollIntoViewBehavior>().Any())
            {
                behaviors.Add(new ScrollIntoViewBehavior());
            }
        }
        else
        {
            //remove any instance of the behavior. (There should only be one, but just in case.)
            foreach (var item in behaviors.ToArray())
            {
                if (item is ScrollIntoViewBehavior)
                    behaviors.Remove(item);
            }
        }
    }


    #endregion
<Style TargetType="Button">
    <Setter Property="Blah:ScrollIntoViewBehavior.IsActive" Value="True" />
</Style>

각 행동에 대해 이것을 작성하는 것은 약간의 PITA입니다.
Stephen Drew 2012

0

비헤이비어 코드에는 Visual이 필요하므로 시각적 개체에만 추가 할 수 있습니다. 따라서 내가 볼 수있는 유일한 옵션은 스타일에 동작을 추가하고 특정 컨트롤의 모든 인스턴스에 영향을 미치도록 ControlTemplate 내부의 요소 중 하나에 추가하는 것입니다.


0

WPF의 연결된 동작 소개 문서 는 스타일 만 사용하여 연결된 동작을 구현하며 관련되거나 도움이 될 수도 있습니다.

"Introduction to Attached Behaviors"기사의 기술은 on Style을 사용하여 상호 작용 태그를 모두 피합니다. 이것이 더 오래된 기술이기 때문인지 또는 일부 시나리오에서 선호해야하는 몇 가지 이점이 여전히 부여되는지 여부는 알 수 없습니다.


2
이것은 Blend 비헤이비어가 아니라 간단한 연결된 속성을 통한 "비헤이비어"입니다.
Stephen Drew 2012


0

개별 행동 / 트리거를 리소스로 선언 :

<Window.Resources>

    <i:EventTrigger x:Key="ET1" EventName="Click">
        <ei:ChangePropertyAction PropertyName="Background">
            <ei:ChangePropertyAction.Value>
                <SolidColorBrush Color="#FFDAD32D"/>
            </ei:ChangePropertyAction.Value>
        </ei:ChangePropertyAction>
    </i:EventTrigger>

</Window.Resources>

컬렉션에 삽입하십시오.

<Button x:Name="Btn1" Content="Button">

        <i:Interaction.Triggers>
             <StaticResourceExtension ResourceKey="ET1"/>
        </i:Interaction.Triggers>

</Button>

4
OP에 어떻게 대답합니까? 방아쇠는 답변의 스타일을 통해 추가되지 않습니다.
Kryptos

0

답변을 기반으로 한 클래스 만 필요하고 행동에 다른 것을 구현할 필요가없는 간단한 솔루션을 만들었습니다.

public static class BehaviorInStyleAttacher
{
    #region Attached Properties

    public static readonly DependencyProperty BehaviorsProperty =
        DependencyProperty.RegisterAttached(
            "Behaviors",
            typeof(IEnumerable),
            typeof(BehaviorInStyleAttacher),
            new UIPropertyMetadata(null, OnBehaviorsChanged));

    #endregion

    #region Getter and Setter of Attached Properties

    public static IEnumerable GetBehaviors(DependencyObject dependencyObject)
    {
        return (IEnumerable)dependencyObject.GetValue(BehaviorsProperty);
    }

    public static void SetBehaviors(
        DependencyObject dependencyObject, IEnumerable value)
    {
        dependencyObject.SetValue(BehaviorsProperty, value);
    }

    #endregion

    #region on property changed methods

    private static void OnBehaviorsChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e)
    {
        if (e.NewValue is IEnumerable == false)
            return;

        var newBehaviorCollection = e.NewValue as IEnumerable;

        BehaviorCollection behaviorCollection = Interaction.GetBehaviors(depObj);
        behaviorCollection.Clear();
        foreach (Behavior behavior in newBehaviorCollection)
        {
            // you need to make a copy of behavior in order to attach it to several controls
            var copy = behavior.Clone() as Behavior;
            behaviorCollection.Add(copy);
        }
    }

    #endregion
}

샘플 사용량은

<Style TargetType="telerik:RadComboBox" x:Key="MultiPeriodSelectableRadComboBox">
    <Setter Property="AllowMultipleSelection" Value="True" />
    <Setter Property="behaviors:BehaviorInStyleAttacher.Behaviors">
        <Setter.Value>
            <collections:ArrayList>
                <behaviors:MultiSelectRadComboBoxBehavior
                        SelectedItems="{Binding SelectedPeriods}"
                        DelayUpdateUntilDropDownClosed="True"
                        SortSelection="True" 
                        ReverseSort="True" />
            </collections:ArrayList>
        </Setter.Value>
    </Setter>
</Style>

ArrayList를 사용하려면이 xmlns를 추가하는 것을 잊지 마십시오.

xmlns:collections="clr-namespace:System.Collections;assembly=mscorlib"
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.