最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c# WPF中System.Windows.Interactivity的使用

 更新時間:2021年03月01日 15:03:57   作者:Hello——尋夢者!  
這篇文章主要介紹了c# WPF中System.Windows.Interactivity的使用,幫助大家更好的理解和學(xué)習(xí)使用c#,感興趣的朋友可以了解下

背景

   在我們進行WPF開發(fā)應(yīng)用程序的時候不可避免的要使用到事件,很多時候沒有嚴格按照MVVM模式進行開發(fā)的時候習(xí)慣直接在xaml中定義事件,然后再在對應(yīng)的.cs文件中直接寫事件的處理過程,這種處理方式寫起來非常簡單而且不用過多地處理考慮代碼之間是否符合規(guī)范,但是我們在寫代碼的時候如果完全按照WPF規(guī)范的MVVM模式進行開發(fā)的時候就應(yīng)該將相應(yīng)的事件處理寫在ViewModel層,這樣整個代碼才更加符合規(guī)范而且層次也更加清楚,更加符合MVVM規(guī)范。

常規(guī)用法

1 引入命名空間

  通過在代碼中引入System.Windows.Interactivity.dll,引入了這個dll后我們就能夠使用這個里面的方法來將事件映射到ViewModel層了,我們來看看具體的使用步驟,第一步就是引入命名控件

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

  另外還可以通過另外一種方式來引入命名空間,其實這兩者間都是對等的。

xmlns:i=http://schemas.microsoft.com/expression/2010/interactivity

2 添加事件對應(yīng)的Command

  這里以TextBox的GetFocus和LostFocus為例來進行說明

<TextBox Text="CommandBinding">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="LostFocus">
            <i:InvokeCommandAction Command="{Binding OnTextLostFocus}"
                                   CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type TextBox}}}"/>
        </i:EventTrigger>
        <i:EventTrigger EventName="GotFocus">
            <i:InvokeCommandAction Command="{Binding OnTextGotFocus}"
                                   CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorLevel=1, AncestorType={x:Type TextBox}}}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</TextBox>

  這個里面我們重點來看看這個InvokeCommandAction的代碼結(jié)構(gòu)

namespace System.Windows.Interactivity
{
    public sealed class InvokeCommandAction : TriggerAction<DependencyObject>
    {
        public static readonly DependencyProperty CommandProperty;
        public static readonly DependencyProperty CommandParameterProperty;
 
        public InvokeCommandAction();
 
        public string CommandName { get; set; }
        public ICommand Command { get; set; }
        public object CommandParameter { get; set; }
 
        protected override void Invoke(object parameter);
    }
}

  這里我們發(fā)現(xiàn)這里我們?nèi)绻覀兌x一個Command的話我們只能夠在Command中獲取到我們綁定的CommandParameter這個參數(shù),但是有時候我們需要獲取到觸發(fā)這個事件的RoutedEventArgs的時候,通過這種方式就很難獲取到了,這個時候我們就需要自己去擴展一個InvokeCommandAction了,這個時候我們應(yīng)該怎么做呢?整個過程分成三步:

2.1 定義自己的CommandParameter

public class ExCommandParameter
{
    /// <summary> 
    /// 事件觸發(fā)源 
    /// </summary> 
    public DependencyObject Sender { get; set; }
    /// <summary> 
    /// 事件參數(shù) 
    /// </summary> 
    public EventArgs EventArgs { get; set; }
    /// <summary> 
    /// 額外參數(shù) 
    /// </summary> 
    public object Parameter { get; set; }
}

  這個對象除了封裝我們常規(guī)的參數(shù)外還封裝了我們需要的EventArgs屬性,有了這個我們就能將當(dāng)前的事件的EventArgs傳遞進來了。

2.2 重寫自己的InvokeCommandAction

public class ExInvokeCommandAction : TriggerAction<DependencyObject>
    {
 
        private string commandName;
        public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(ExInvokeCommandAction), null);
        public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(object), typeof(ExInvokeCommandAction), null);
        /// <summary> 
        /// 獲得或設(shè)置此操作應(yīng)調(diào)用的命令的名稱。 
        /// </summary> 
        /// <value>此操作應(yīng)調(diào)用的命令的名稱。</value> 
        /// <remarks>如果設(shè)置了此屬性和 Command 屬性,則此屬性將被后者所取代。</remarks> 
        public string CommandName
        {
            get
            {
                base.ReadPreamble();
                return this.commandName;
            }
            set
            {
                if (this.CommandName != value)
                {
                    base.WritePreamble();
                    this.commandName = value;
                    base.WritePostscript();
                }
            }
        }
        /// <summary> 
        /// 獲取或設(shè)置此操作應(yīng)調(diào)用的命令。這是依賴屬性。 
        /// </summary> 
        /// <value>要執(zhí)行的命令。</value> 
        /// <remarks>如果設(shè)置了此屬性和 CommandName 屬性,則此屬性將優(yōu)先于后者。</remarks> 
        public ICommand Command
        {
            get
            {
                return (ICommand)base.GetValue(ExInvokeCommandAction.CommandProperty);
            }
            set
            {
                base.SetValue(ExInvokeCommandAction.CommandProperty, value);
            }
        }
        /// <summary> 
        /// 獲得或設(shè)置命令參數(shù)。這是依賴屬性。 
        /// </summary> 
        /// <value>命令參數(shù)。</value> 
        /// <remarks>這是傳遞給 ICommand.CanExecute 和 ICommand.Execute 的值。</remarks> 
        public object CommandParameter
        {
            get
            {
                return base.GetValue(ExInvokeCommandAction.CommandParameterProperty);
            }
            set
            {
                base.SetValue(ExInvokeCommandAction.CommandParameterProperty, value);
            }
        }
        /// <summary> 
        /// 調(diào)用操作。 
        /// </summary> 
        /// <param name="parameter">操作的參數(shù)。如果操作不需要參數(shù),則可以將參數(shù)設(shè)置為空引用。</param> 
        protected override void Invoke(object parameter)
        {
            if (base.AssociatedObject != null)
            {
                ICommand command = this.ResolveCommand();
                /*
                 * ★★★★★★★★★★★★★★★★★★★★★★★★
                 * 注意這里添加了事件觸發(fā)源和事件參數(shù)
                 * ★★★★★★★★★★★★★★★★★★★★★★★★
                 */
                ExCommandParameter exParameter = new ExCommandParameter
                {
                    Sender = base.AssociatedObject,
                    Parameter = GetValue(CommandParameterProperty),
                    EventArgs = parameter as EventArgs
                };
                if (command != null && command.CanExecute(exParameter))
                {
                    /*
                     * ★★★★★★★★★★★★★★★★★★★★★★★★
                     * 注意將擴展的參數(shù)傳遞到Execute方法中
                     * ★★★★★★★★★★★★★★★★★★★★★★★★
                     */
                    command.Execute(exParameter);
                }
            }
        }
        private ICommand ResolveCommand()
        {
            ICommand result = null;
            if (this.Command != null)
            {
                result = this.Command;
            }
            else
            {
                if (base.AssociatedObject != null)
                {
                    Type type = base.AssociatedObject.GetType();
                    PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
                    PropertyInfo[] array = properties;
                    for (int i = 0; i < array.Length; i++)
                    {
                        PropertyInfo propertyInfo = array[i];
                        if (typeof(ICommand).IsAssignableFrom(propertyInfo.PropertyType) && string.Equals(propertyInfo.Name, this.CommandName, StringComparison.Ordinal))
                        {
                            result = (ICommand)propertyInfo.GetValue(base.AssociatedObject, null);
                        }
                    }
                }
            }
            return result;
        }
 
    } 

  這個里面的重點是要重寫基類中的Invoke方法,將當(dāng)前命令通過反射的方式來獲取到,然后在執(zhí)行command.Execute方法的時候?qū)⑽覀冏远x的ExCommandParameter傳遞進去,這樣我們就能夠在最終綁定的命令中獲取到特定的EventArgs對象了。

2.3 在代碼中應(yīng)用自定義InvokeCommandAction

  <ListBox x:Name="lb_selecthistorymembers"                         
           SnapsToDevicePixels="true"
           ItemsSource="{Binding DataContext.SpecificHistoryMembers,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=my:AnnouncementApp},Mode=TwoWay}"
           HorizontalAlignment="Stretch"
           ScrollViewer.HorizontalScrollBarVisibility="Disabled"
           Background="#fff"
           BorderThickness="1">
           <i:Interaction.Triggers>
              <i:EventTrigger EventName="SelectionChanged">
                 <interactive:ExInvokeCommandAction Command="{Binding DataContext.OnSelectHistoryMembersListBoxSelected,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=my:AnnouncementApp},Mode=TwoWay}"
                              CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListBox}}">
                 </interactive:ExInvokeCommandAction>
              </i:EventTrigger>
          </i:Interaction.Triggers>       
</ListBox>

  注意這里需要首先引入自定義的interactive的命名空間,這個在使用的時候需要注意,另外在最終的Command訂閱中EventArgs根據(jù)不同的事件有不同的表現(xiàn)形式,比如Loaded事件,那么最終獲取到的EventArgs就是RoutedEventArgs對象,如果是TableControl的SelectionChanged事件,那么最終獲取到的就是SelectionChangedEventArgs對象,這個在使用的時候需要加以區(qū)分。

3  使用當(dāng)前程序集增加Behavior擴展

  System.Windows.Interactivity.dll中一個重要的擴展就是對Behavior的擴展,這個Behavior到底該怎么用呢?我們來看下面的一個例子,我們需要給一個TextBlock和Button增加一個統(tǒng)一的DropShadowEffect,我們先來看看最終的效果,然后再就具體的代碼進行分析。

代碼分析

  1 增加一個EffectBehavior

public class EffectBehavior : Behavior<FrameworkElement>
 {
 protected override void OnAttached()
 {
 base.OnAttached();

 AssociatedObject.MouseEnter += AssociatedObject_MouseEnter;
 AssociatedObject.MouseLeave += AssociatedObject_MouseLeave;
 }

 private void AssociatedObject_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
 {
 var element = sender as FrameworkElement;
 element.Effect = new DropShadowEffect() { Color = Colors.Transparent, ShadowDepth = 2 }; ;
 }

 private void AssociatedObject_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e)
 {
 var element = sender as FrameworkElement;
 element.Effect = new DropShadowEffect() { Color = Colors.Red, ShadowDepth = 2 };
 }

 protected override void OnDetaching()
 {
 base.OnDetaching();
 AssociatedObject.MouseEnter -= AssociatedObject_MouseEnter;
 AssociatedObject.MouseLeave -= AssociatedObject_MouseLeave;

 }
 }

  這里我們繼承自System.Windows.Interactivity中的Behavior<T>這個泛型類,這里我們的泛型參數(shù)使用FrameworkElement,因為大部分的控件都是繼承自這個對象,我們方便為其統(tǒng)一添加效果,在集成這個基類后我們需要重寫基類的OnAttached和OnDetaching方法,這個里面AssociatedObject就是我們具體添加Effect的元素,在我們的示例中這個分別是TextBlock和Button對象。

  2 在具體的控件中添加此效果

<Window x:Class="WpfBehavior.MainWindow"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 xmlns:local="clr-namespace:WpfBehavior"
 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
 mc:Ignorable="d"
 Title="MainWindow" Height="450" Width="800">
 <Grid>
 <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center">
 <TextBlock Text="測試文本" Margin="2" Height="30">
 <i:Interaction.Behaviors>
 <local:EffectBehavior></local:EffectBehavior>
 </i:Interaction.Behaviors>
 </TextBlock>
 <Button Content="測試" Width="80" Height="30" Margin="2">
 <i:Interaction.Behaviors>
 <local:EffectBehavior></local:EffectBehavior>
 </i:Interaction.Behaviors>
 </Button>
 </StackPanel>
 </Grid>
</Window>

以上就是c# WPF中System.Windows.Interactivity的使用的詳細內(nèi)容,更多關(guān)于WPF中System.Windows.Interactivity的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Unity UGUI的Scrollbar滾動條組件使用詳解

    Unity UGUI的Scrollbar滾動條組件使用詳解

    這篇文章主要介紹了Unity UGUI的Scrollbar(滾動條)組件的介紹及使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • C#字符串與正則表達式的圖文詳解

    C#字符串與正則表達式的圖文詳解

    正則表達式是個非常好的工具,它的作用主要是用簡單的有規(guī)則的表達式來檢索和匹配一段字符串,這篇文章主要給大家介紹了關(guān)于C#字符串與正則表達式的相關(guān)資料,需要的朋友可以參考下
    2022-09-09
  • C# 網(wǎng)絡(luò)編程之UDP

    C# 網(wǎng)絡(luò)編程之UDP

    這篇文章主要介紹了C# 網(wǎng)絡(luò)編程之UDP的相關(guān)資料,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下
    2021-02-02
  • Unity實現(xiàn)刮獎效果

    Unity實現(xiàn)刮獎效果

    這篇文章主要為大家詳細介紹了Unity實現(xiàn)刮獎效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • DevExpress之ChartControl實現(xiàn)時間軸實例

    DevExpress之ChartControl實現(xiàn)時間軸實例

    這篇文章主要介紹了DevExpress中ChartControl實現(xiàn)時間軸的方法,涉及相關(guān)C#繪圖程序用法,具有一定的實用價值,需要的朋友可以參考下
    2014-10-10
  • C# 判斷字符串為空的幾種辦法

    C# 判斷字符串為空的幾種辦法

    C# 判斷字符串為空的幾種辦法,需要的朋友可以參考一下
    2013-04-04
  • c#通過app.manifest使程序以管理員身份運行

    c#通過app.manifest使程序以管理員身份運行

    通常我們使用c#編寫的程序不會彈出這個提示,也就無法以管理員身分運行。微軟的操作系統(tǒng)使用微軟的產(chǎn)品方法當(dāng)然是有的,通過app.manifest配置可以使程序打開的時候,彈出UAC提示需要得到允許才可以繼續(xù),這樣就獲得了管理員的權(quán)限來執(zhí)行程序
    2015-01-01
  • WinForm 自動完成控件實例代碼簡析

    WinForm 自動完成控件實例代碼簡析

    在Web的應(yīng)用方面有js的插件實現(xiàn)自動完成(或叫智能提示)功能,但在WinForm窗體應(yīng)用方面就沒那么好了,接下來參考一下這個實例,看看有沒有以外收獲,感興趣的朋友可以了解下啊,希望本文對你有幫助啊
    2013-01-01
  • 關(guān)于C#泛型列表List<T>的基本用法總結(jié)

    關(guān)于C#泛型列表List<T>的基本用法總結(jié)

    本篇文章主要是對C#中泛型列表List<T>的基本用法進行了詳細的總結(jié)介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2014-01-01
  • 基于C#實現(xiàn)屏幕取色器的示例詳解

    基于C#實現(xiàn)屏幕取色器的示例詳解

    這篇文章主要為大家詳細介紹了如何利用C#實現(xiàn)屏幕取色器,文中的示例代碼講解詳細,對我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以了解一下
    2022-12-12

最新評論

茂名市| 嘉荫县| 法库县| 汶上县| 原平市| 平舆县| 滁州市| 萝北县| 博乐市| 潮安县| 磐安县| 开封县| 嘉定区| 武夷山市| 北京市| 醴陵市| 宝清县| 雷山县| 济宁市| 宁海县| 屯昌县| 廉江市| 海伦市| 上思县| 汉川市| 灌云县| 樟树市| 德阳市| 阿鲁科尔沁旗| 开鲁县| 斗六市| 巫山县| 新竹市| 丹阳市| 尤溪县| 眉山市| 芮城县| 怀仁县| 安泽县| 永嘉县| 拜泉县|