• <menu id="w2i4a"></menu>
  • logo DevExpress WinForm中文手冊(cè)

    命令行


    立即下載DevExpress WinForms

    在標(biāo)準(zhǔn)的WinForms應(yīng)用程序中,操作通常在事件處理程序中執(zhí)行。例如,要在用戶單擊按鈕時(shí)刷新數(shù)據(jù),需要處理ButtonClick事件并檢索數(shù)據(jù)源記錄。

    這種標(biāo)準(zhǔn)技術(shù)不適合分離層的MVVM概念,從數(shù)據(jù)源中提取數(shù)據(jù)的代碼應(yīng)該屬于ViewModel層,而不是View層。在MVVM中,這些任務(wù)是通過(guò)封裝動(dòng)作的命令ViewModel對(duì)象來(lái)完成的,將UI元素綁定到此對(duì)象來(lái)實(shí)現(xiàn)所需的層分離:視圖代碼現(xiàn)在只有綁定代碼,而所有業(yè)務(wù)邏輯都保留在ViewModel中,并且可以安全地更改。

    DevExpress MVVM框架將所有public void方法視為可綁定的命令。下面的代碼說(shuō)明了如何聲明使用Service顯示消息框的命令,您可以通過(guò)以下鏈接在DevExpress demo Center中查看完整的演示。

    C#:

    //POCO ViewModel
    public class ViewModelWithSimpleCommand {
    //command
    public void DoSomething() {
    var msgBoxService = this.GetService<IMessageBoxService>();
    msgBoxService.ShowMessage("Hello!");
    }
    }

    VB.NET:

    'POCO ViewModel
    Public Class ViewModelWithSimpleCommand
    'command
    Public Sub DoSomething()
    Dim msgBoxService = Me.GetService(Of IMessageBoxService)()
    msgBoxService.ShowMessage("Hello!")
    End Sub
    End Class

    注意:名稱以“Command”結(jié)尾的方法將引發(fā)異?!孛祟惙椒ɑ蚴褂肅ommand屬性修飾它們。

    要將按鈕鏈接到此命令,請(qǐng)使用BindCommand或WithCommand方法。

    C#:

    //View code
    mvvmContext.ViewModelType = typeof(ViewModelWithSimpleCommand);
    var fluent = mvvmContext.OfType<ViewModelWithSimpleCommand>();
    fluent.BindCommand(commandButton, x => x.DoSomething);
    \\or
    fluent.WithCommand(x => x.DoSomething)
    .Bind(commandButton1);

    VB.NET:

    'View code
    mvvmContext.ViewModelType = GetType(ViewModelWithSimpleCommand)
    Dim fluent = mvvmContext.OfType(Of ViewModelWithSimpleCommand)()
    fluent.BindCommand(commandButton, Sub(x) x.DoSomething)
    'or
    fluent.WithCommand(Sub(x) x.DoSomething)
    .Bind(commandButton1)

    WithCommand方法允許您同時(shí)綁定多個(gè)按鈕。

    運(yùn)行演示:綁定到多個(gè)UI元素。

    C#:

    //View
    var fluent = mvvmContext.OfType<ViewModelWithSimpleCommand>();
    fluent.WithCommand(x => x.DoSomething)
    .Bind(commandButton1)
    .Bind(commandButton2);

    VB.NET:

    'View
    Dim fluent = mvvmContext.OfType(Of ViewModelWithSimpleCommand)()
    fluent.WithCommand(Sub(x) x.DoSomething)
    .Bind(commandButton1)
    .Bind(commandButton2)

    可執(zhí)行條件

    要指定判斷命令是否應(yīng)該運(yùn)行的條件,請(qǐng)聲明一個(gè)Boolean method,該方法的名稱以“Can”開(kāi)頭,后面跟著相關(guān)的命令名稱,這些方法被稱為CanExecute conditions。

    C#:

    //ViewModel
    public class ViewModelWithConditionalCommand {
    //Command
    public void DoSomething() {
    var msgBoxService = this.GetService<IMessageBoxService>();
    msgBoxService.ShowMessage("Hello!");
    }
    //CanExecute condition
    public bool CanDoSomething() {
    return (2 + 2) == 4;
    }
    }

    VB.NET:

    'ViewModel
    Public Class ViewModelWithConditionalCommand
    'Command
    Public Sub DoSomething()
    Dim msgBoxService = Me.GetService(Of IMessageBoxService)()
    msgBoxService.ShowMessage("Hello!")
    End Sub
    'CanExecute condition
    Public Function CanDoSomething() As Boolean
    Return (2 + 2) = 4
    End Function
    End Class

    您也可以忽略CanExecute名稱要求,并使用Command屬性手動(dòng)分配命令條件。

    C#:

    [Command(CanExecuteMethodName = "DoSomethingCriteria")]
    public void DoSomething(int p) {
    //command
    }

    VB.NET:

    <Command(CanExecuteMethodName := "DoSomethingCriteria")>
    Public Sub DoSomething(ByVal p As Integer)
    'command
    End Sub

    如果CanExecute條件返回false,框架將改變鏈接到該命令的UI元素的狀態(tài)(禁用、取消選中或隱藏該元素)。上面的代碼示例來(lái)自以下演示:運(yùn)行此演示并更改條件,使其始終返回false,“執(zhí)行命令”按鈕被禁用,因?yàn)樗南嚓P(guān)命令不能再運(yùn)行。

    C#:

    //ViewModel
    public bool CanDoSomething() {
    //always "false"
    return (2 + 2) == 5;
    }

    VB.NET:

    'ViewModel
    Public Function CanDoSomething() As Boolean
    'always "False"
    Return (2 + 2) = 5
    End Function

    當(dāng)發(fā)生以下情況時(shí),框架會(huì)檢查CanExecute條件:

    • UI命令綁定初始化。
    • 調(diào)用RaiseCanExecuteChanged方法。在下面的示例中,每次SelectedEntity屬性更改時(shí),都會(huì)重新檢查CanDoSomething條件的返回值。

    C#:

    //Bindable Property
    public virtual MyEntity SelectedEntity{ get; set; }
    
    //OnChanged callback for the bindable property
    protected void OnSelectedEntityChanged(){
    this.RaiseCanExecuteChanged(x=>x.DoSomething());
    }
    
    //Command
    public void DoSomething() {
    //. . .
    }
    
    //CanExecute condition
    public bool CanDoSomething() {
    //. . .
    }

    VB.NET:

    'Bindable Property
    Public Overridable Property SelectedEntity() As MyEntity
    
    'OnChanged callback for the bindable property
    Protected Sub OnSelectedEntityChanged()
    Me.RaiseCanExecuteChanged(Function(x) x.DoSomething())
    End Sub
    
    'Command
    Public Sub DoSomething()
    '. . .
    End Sub
    
    'CanExecute condition
    Public Function CanDoSomething() As Boolean
    '. . .
    End Function

    命令與參數(shù)

    DevExpress MVVM框架接受public void方法作為參數(shù)化命令,您可以使用這個(gè)參數(shù)在View和ViewModel之間傳遞數(shù)據(jù)。

    運(yùn)行demo:Parameterized命令。

    C#:

    //ViewModel
    public class ViewModelWithParametrizedCommand {
    public void DoSomething(object p) {
    var msgBoxService = this.GetService<IMessageBoxService>();
    msgBoxService.ShowMessage(string.Format("The parameter is {0}.", p));
    }
    }
    
    //View
    mvvmContext.ViewModelType = typeof(ViewModelWithParametrizedCommand);
    var fluent = mvvmContext.OfType<ViewModelWithParametrizedCommand>();
    object parameter = 5;
    fluent.BindCommand(commandButton, x => x.DoSomething, x => parameter);

    VB.NET:

    'ViewModel
    Public Class ViewModelWithParametrizedCommand
    Public Sub DoSomething(ByVal p As Object)
    Dim msgBoxService = Me.GetService(Of IMessageBoxService)()
    msgBoxService.ShowMessage(String.Format("The parameter is {0}.", p))
    End Sub
    End Class
    
    'View
    mvvmContext.ViewModelType = GetType(ViewModelWithParametrizedCommand)
    Dim fluent = mvvmContext.OfType(Of ViewModelWithParametrizedCommand)()
    Dim parameter As Object = 5
    fluent.BindCommand(commandButton, Sub(x) x.DoSomething(Nothing), Function(x) parameter)

    還可以在CanExecute條件中添加參數(shù)。

    運(yùn)行demo:帶CanExecute條件的參數(shù)化命令。

    C#:

    //ViewModel
    public class ViewModelWithParametrizedConditionalCommand {
    public void DoSomething(int p) {
    var msgBoxService = this.GetService<IMessageBoxService>();
    msgBoxService.ShowMessage(string.Format(
    "The parameter is {0}.", p));
    }
    public bool CanDoSomething(int p) {
    return (2 + 2) == p;
    }
    }
    
    //View
    mvvmContext.ViewModelType = typeof(ViewModelWithParametrizedConditionalCommand);
    var fluent = mvvmContext.OfType<ViewModelWithParametrizedConditionalCommand>();
    int parameter = 4;
    fluent.BindCommand(commandButton, x => x.DoSomething, x => parameter);

    VB.NET:

    'ViewModel
    Public Class ViewModelWithParametrizedConditionalCommand
    Public Sub DoSomething(ByVal p As Integer)
    Dim msgBoxService = Me.GetService(Of IMessageBoxService)()
    msgBoxService.ShowMessage(String.Format("The parameter is {0}.", p))
    End Sub
    Public Function CanDoSomething(ByVal p As Integer) As Boolean
    Return (2 + 2) = p
    End Function
    End Class
    
    'View
    mvvmContext.ViewModelType = GetType(ViewModelWithParametrizedConditionalCommand)
    Dim fluent = mvvmContext.OfType(Of ViewModelWithParametrizedConditionalCommand)()
    Dim parameter As Integer = 4
    fluent.BindCommand(commandButton, Sub(x) x.DoSomething(Nothing), Function(x) parameter)
    多參數(shù)

    使用對(duì)象或元組數(shù)據(jù)結(jié)構(gòu)來(lái)傳遞多個(gè)參數(shù)。

    C#:

    class Parameters{
    public int Parameter1 { get; set }
    public string Parameter2 { get; set }
    ...
    }
    // ...
    mvvmContext.OfType<MouseDownAwareViewModel>()
    .WithEvent<MouseEventArgs>(label, "MouseDown")
    .EventToCommand(x => x.ReportLocation, args => new Parameters{ Parameter1 = 1, Parameter2 = "2" });

    VB.NET:

    Friend Class Parameters
    Public Property Parameter1() As Integer
    Get
    Set(ByVal value As Integer)
    End Set
    End Get
    public String Parameter2
    Get
    Set(ByVal value As Integer)
    End Set
    End Get
    ...
    ' ...
    mvvmContext.OfType(Of MouseDownAwareViewModel)().WithEvent(Of MouseEventArgs)(label, "MouseDown").EventToCommand(Function(x) x.ReportLocation, Function(args) New Parameters With {.Parameter1 = 1, .Parameter2 = "2"})

    異步命令

    如果需要執(zhí)行延遲或連續(xù)的操作,請(qǐng)使用異步命令。要?jiǎng)?chuàng)建一個(gè)異步命令,聲明一個(gè)System.Threading.Tasks.Task類型的公共方法(也可以使用async/await語(yǔ)法),將UI元素綁定到命令的代碼保持不變,框架在命令運(yùn)行時(shí)禁用此元素。

    執(zhí)行demo:Async命令。

    C#:

    //ViewModel
    public class ViewModelWithAsyncCommand {
    public async Task DoSomethingAsync() {
    // do some work here
    await Task.Delay(1000);
    }
    }
    
    //View
    mvvmContext.ViewModelType = typeof(ViewModelWithAsyncCommand);
    var fluent = mvvmContext.OfType<ViewModelWithAsyncCommand>();
    fluent.BindCommand(commandButton, x => x.DoSomethingAsync);

    VB.NET:

    'ViewModel
    Public Class ViewModelWithAsyncCommand
    Public Async Sub DoSomethingAsync() As Task
    ' do some work here
    Await Task.Delay(1000)
    End Sub
    End Class
    
    'View
    mvvmContext.ViewModelType = GetType(ViewModelWithAsyncCommand)
    Dim fluent = mvvmContext.OfType(Of ViewModelWithAsyncCommand)()
    fluent.BindCommand(commandButton, Sub(x) x.DoSomethingAsync(Nothing))

    任務(wù)支持取消標(biāo)記并允許您檢查IsCancellationRequested屬性,并在該屬性返回true時(shí)中止任務(wù)。如果將此代碼添加到async命令中,請(qǐng)使用BindCancelCommand方法創(chuàng)建一個(gè)UI元素來(lái)停止正在執(zhí)行的async命令。DevExpress MVVM框架鎖定了這個(gè)取消按鈕,只有在運(yùn)行相關(guān)的異步命令時(shí)才啟用它。

    執(zhí)行demo: Async取消命令。

    C#:

    //ViewModel
    public class ViewModelWithAsyncCommandAndCancellation {
    public async Task DoSomethingAsynchronously() {
    var dispatcher = this.GetService<IDispatcherService>();
    var asyncCommand = this.GetAsyncCommand(x => x.DoSomethingAsynchronously());
    for(int i = 0; i <= 100; i++) {
    if(asyncCommand.IsCancellationRequested)
    break;
    // do some work here
    await Task.Delay(25);
    await UpdateProgressOnUIThread(dispatcher, i);
    }
    await UpdateProgressOnUIThread(dispatcher, 0);
    }
    
    public int Progress {
    get;
    private set;
    }
    //update the "Progress" property bound to the progress bar within a View
    async Task UpdateProgressOnUIThread(IDispatcherService dispatcher, int progress) {
    await dispatcher.BeginInvoke(() => {
    Progress = progress;
    this.RaisePropertyChanged(x => x.Progress);
    });
    }
    }
    
    //View
    mvvmContext.ViewModelType = typeof(ViewModelWithAsyncCommandAndCancellation);
    var fluent = mvvmContext.OfType<ViewModelWithAsyncCommandAndCancellation>();
    fluent.BindCommand(commandButton, x => x.DoSomethingAsynchronously);
    fluent.BindCancelCommand(cancelButton, x => x.DoSomethingAsynchronously);
    fluent.SetBinding(progressBar, p => p.EditValue, x => x.Progress);

    VB.NET:

    'ViewModel
    Public Class ViewModelWithAsyncCommandAndCancellation
    Public Async Sub DoSomethingAsynchronously() As Task
    Dim dispatcher = Me.GetService(Of IDispatcherService)()
    Dim asyncCommand = Me.GetAsyncCommand(Sub(x) x.DoSomethingAsynchronously())
    For i As Integer = 0 To 100
    If asyncCommand.IsCancellationRequested Then
    Exit For
    End If
    ' do some work here
    Await Task.Delay(25)
    Await UpdateProgressOnUIThread(dispatcher, i)
    Next i
    Await UpdateProgressOnUIThread(dispatcher, 0)
    End Sub
    
    Private privateProgress As Integer
    Public Property Progress() As Integer
    Get
    Return privateProgress
    End Get
    Private Set(ByVal value As Integer)
    privateProgress = value
    End Set
    End Property
    'update the "Progress" property bound to the progress bar within a View
    Private Async Sub UpdateProgressOnUIThread(ByVal dispatcher As IDispatcherService, ByVal progress As Integer) As Task
    Await dispatcher.BeginInvoke(Sub()
    Me.Progress = progress
    Me.RaisePropertyChanged(Sub(x) x.Progress)
    End Sub)
    End Sub
    End Class
    
    'View
    mvvmContext.ViewModelType = GetType(ViewModelWithAsyncCommandAndCancellation)
    Dim fluent = mvvmContext.OfType(Of ViewModelWithAsyncCommandAndCancellation)()
    fluent.BindCommand(commandButton, Sub(x) x.DoSomethingAsynchronously)
    fluent.BindCancelCommand(cancelButton, Sub(x) x.DoSomethingAsynchronously)
    fluent.SetBinding(progressBar, Sub(p) p.EditValue, Sub(x) x.Progress)

    WithCommand Fluent API方法還支持可取消的異步命令。

    C#:

    mvvmContext.ViewModelType = typeof(ViewModelWithAsyncCommandAndCancellation);
    // Initialize the Fluent API
    var fluent = mvvmContext.OfType<ViewModelWithAsyncCommandAndCancellation>();
    // Binding for buttons
    fluent.WithCommand(x => x.DoSomethingAsynchronously)
    .Bind(commandButton)
    .BindCancel(cancelButton);

    VB.NET:

    mvvmContext.ViewModelType = GetType(ViewModelWithAsyncCommandAndCancellation)
    ' Initialize the Fluent API
    Dim fluent = mvvmContext.OfType(Of ViewModelWithAsyncCommandAndCancellation)()
    ' Binding for buttons
    fluent.WithCommand(Sub(x) x.DoSomethingAsynchronously).Bind(commandButton).BindCancel(cancelButton)

    命令觸發(fā)器

    觸發(fā)器允許您執(zhí)行與命令關(guān)聯(lián)的其他View操作。有三種觸發(fā)器類型,取決于觸發(fā)觸發(fā)器的條件:

    • “Before”觸發(fā)器——允許您在目標(biāo)命令執(zhí)行之前執(zhí)行操作。

    C#:

    mvvmContext.ViewModelType = typeof(ViewModelWithSimpleCommand);
    var fluent = mvvmContext.OfType<ViewModelWithSimpleCommand>();
    fluent.BindCommand(commandButton, x => x.DoSomething);
    fluent.WithCommand(x => x.DoSomething)
    .Before(() => XtraMessageBox.Show("The target command is about to be executed"));

    VB.NET:

    mvvmContext.ViewModelType = GetType(ViewModelWithSimpleCommand)
    Dim fluent = mvvmContext.OfType(Of ViewModelWithSimpleCommand)()
    fluent.BindCommand(commandButton, Function(x) x.DoSomething)
    fluent.WithCommand(Sub(x) x.DoSomething)
    .Before(Function() XtraMessageBox.Show("The target command is about to be executed"))
    • " After "觸發(fā)器——允許您在目標(biāo)命令完成后執(zhí)行操作。

    C#:

    mvvmContext.ViewModelType = typeof(ViewModelWithSimpleCommand);
    var fluent = mvvmContext.OfType<ViewModelWithSimpleCommand>();
    fluent.BindCommand(commandButton, x => x.DoSomething);
    fluent.WithCommand(x => x.DoSomething)
    .After(() => XtraMessageBox.Show("The target command has been executed"));

    VB.NET:

    mvvmContext.ViewModelType = GetType(ViewModelWithSimpleCommand)
    Dim fluent = mvvmContext.OfType(Of ViewModelWithSimpleCommand)()
    fluent.BindCommand(commandButton, Function(x) x.DoSomething)
    fluent.WithCommand(Function(x) x.DoSomething).After(Function() XtraMessageBox.Show("The target command has been executed"))
    • “CanExecute”條件觸發(fā)器——允許您在目標(biāo)命令的CanExecute條件發(fā)生變化時(shí)執(zhí)行操作。

    C#:

    var fluent = mvvmContext.OfType<ViewModelWithSimpleCommandAndCanExecute>();
    fluent.BindCommand(commandButton, x => x.DoSomething);
    // When the CanExecute condition changes, the message shows up
    fluent.WithCommand(x => x.DoSomething)
    .OnCanExecuteChanged(() => XtraMessageBox.Show("The CanExecute condition has changed"));

    VB.NET:

    Dim fluent = mvvmContext.OfType(Of ViewModelWithSimpleCommandAndCanExecute)()
    fluent.BindCommand(commandButton, Function(x) x.DoSomething)
    ' When the CanExecute condition changes, the message shows up
    fluent.WithCommand(Function(x) x.DoSomething)
    .OnCanExecuteChanged(Function() XtraMessageBox.Show("The CanExecute condition has changed"))

    注意,每個(gè)綁定到目標(biāo)命令的UI元素都會(huì)執(zhí)行觸發(fā)器,當(dāng)單擊任何按鈕時(shí),下面的代碼示例將顯示一個(gè)消息框。

    C#:

    mvvmContext1.OfType<BulkEditViewModel>()
    .WithCommand(vm => vm.RemoveFields())
    .Bind(button1)
    .Bind(button2)
    .After(() => MessageBox.Show("Test"));

    VB.NET:

    mvvmContext1.OfType(Of BulkEditViewModel)()
    .WithCommand(Function(vm) vm.RemoveFields())
    .Bind(button1)
    .Bind(button2)
    .After(Function() MessageBox.Show("Test"))

    Non-POCO命令

    上面描述的POCO類命令允許您使用最直接且不會(huì)出錯(cuò)的語(yǔ)法,DevExpress MVVM框架還支持其他命令類型來(lái)確保遺留項(xiàng)目的無(wú)障礙遷移。

    DevExpress delegate命令對(duì)象

    委托命令是System.Windows.Input.ICommand接口的實(shí)現(xiàn)。

    運(yùn)行demo: Simple Commands

    C#:

    DelegateCommand command = new DelegateCommand(() => {
    XtraMessageBox.Show("Hello!");
    });
    commandButton.BindCommand(command);

    VB.NET:

    Dim command As New DelegateCommand(Sub() XtraMessageBox.Show("Hello!"))
    commandButton.BindCommand(command)

    運(yùn)行demo:帶有CanExecute條件的命令

    C#:

    Func<bool> canExecute = () => (2 + 2 == 4);
    DelegateCommand command = new DelegateCommand(() => {
    XtraMessageBox.Show("Hello!");
    }, canExecute);
    commandButton.BindCommand(command);

    VB.NET:

    Dim canExecute As Func(Of Boolean) = Function() (2 + 2 = 4)
    Dim command As New DelegateCommand(Sub() XtraMessageBox.Show("Hello!"), canExecute)
    commandButton.BindCommand(command)

    運(yùn)行demo:帶參數(shù)命令

    C#:

    DelegateCommand<object> command = new DelegateCommand<object>((v) => {
    XtraMessageBox.Show(string.Format("The parameter is {0}.", v));
    });
    object parameter = 5;
    commandButton.BindCommand(command, () => parameter);

    VB.NET:

    Dim command As New DelegateCommand(Of Object)(Sub(v) XtraMessageBox.Show(String.Format("The parameter is {0}.", v)))
    Dim parameter As Object = 5
    commandButton.BindCommand(command, Function() parameter)

    運(yùn)行demo:參數(shù)化CanExecute條件的命令

    C#:

    Func<int, bool> canExecute = (p) => (2 + 2 == p);
    DelegateCommand<int> command = new DelegateCommand<int>((v) => {
    XtraMessageBox.Show(string.Format("The parameter is {0}.", v));
    }, canExecute);
    int parameter = 4;
    commandButton.BindCommand(command, () => parameter);

    VB.NET:

    Dim canExecute As Func(Of Integer, Boolean) = Function(p) (2 + 2 = p)
    Dim command As New DelegateCommand(Of Integer)(Sub(v) XtraMessageBox.Show(String.Format("The parameter is {0}.", v)), canExecute)
    Dim parameter As Integer = 4
    commandButton.BindCommand(command, Function() parameter)
    自定義命令類

    這些對(duì)象是具有至少一個(gè)Execute方法的任意自定義類型的對(duì)象,如果需要您可以添加CanExecute方法和CanExecuteChanged事件。

    運(yùn)行demo:Simple Commands

    C#:

    CommandObject command = new CommandObject();
    commandButton.BindCommand(command);
    
    public class CommandObject {
    public void Execute(object parameter) {
    XtraMessageBox.Show("Hello!");
    }
    }

    VB.NET:

    Private command As New CommandObject()
    commandButton.BindCommand(command)
    
    Public Class CommandObject
    Public Sub Execute(ByVal parameter As Object)
    XtraMessageBox.Show("Hello!")
    End Sub
    End Class

    運(yùn)行demo:帶參數(shù)命令

    C#:

    CommandObjectWithParameter command = new CommandObjectWithParameter();
    int parameter = 4;
    commandButton.BindCommand(command, () => parameter);
    
    public class CommandObjectWithParameter {
    public void Execute(object parameter) {
    XtraMessageBox.Show(string.Format(
    "The parameter is {0}.", parameter));
    }
    public bool CanExecute(object parameter) {
    return object.Equals(2 + 2, parameter);
    }
    }

    VB.NET:

    Dim command As New CommandObjectWithParameter()
    Dim parameter As Integer = 4
    commandButton.BindCommand(command, Sub() parameter)
    
    Public Class CommandObjectWithParameter
    Public Sub Execute(ByVal parameter As Object)
    XtraMessageBox.Show(String.Format("The parameter is {0}.", parameter))
    End Sub
    Public Function CanExecute(ByVal parameter As Object) As Boolean
    Return Object.Equals(2 + 2, parameter)
    End Function
    End Class
    掃碼咨詢


    添加微信 立即咨詢

    電話咨詢

    客服熱線
    023-68661681

    TOP
    三级成人熟女影院,欧美午夜成人精品视频,亚洲国产成人乱色在线观看,色中色成人论坛 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();