使用样式设置器WPF中的参数绑定到命令

时间:2017-03-24 10:32:32

标签: c# wpf xaml data-binding routed-commands

我在WPF中编写了一个桌面应用程序,它有一个控件可以在动态创建的选项卡上运行。 我通过样式设置器将CloseTabCommand绑定到控件的CloseCommand属性。

<Style TargetType="cc:SearchTab">
    <Setter Property="CloseCommand" Value="{Binding CloseTabCommand}"/>
    <Setter Property="CaptionImage" Value="{dx:DXImage Image=Lookup&amp;Reference_16x16.png}"/>
</Style>

我想将{RelativeSource Self}作为命令参数传递给CloseTabCommand以获取实际的tab实例,并将其从代码隐藏中删除。 但我不知道如何存档。

这是完整的xaml视图定义:

<UserControl
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:dxthm="clr-namespace:DevExpress.Xpf.Utils.Themes;assembly=DevExpress.Xpf.Core.v16.2"
         xmlns:dxr="http://schemas.devexpress.com/winfx/2008/xaml/ribbon"
         xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
         xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
         xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
         xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
         xmlns:view="clr-namespace:ConfigOcean.View" 
         xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
         xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Platform"
         xmlns:cc="clr-namespace:Arc.Stork.ConfigOcean.CustomControls"
         x:Class="Arc.Stork.ConfigOcean.View.MainView"   
         mc:Ignorable="d"
         d:DesignHeight="300" d:DesignWidth="300"
         DataContext="{Binding Main, Source={StaticResource Locator}}">
<UserControl.Resources>
    <ResourceDictionary>
        <view:UsersSearchView x:Key="UsersSearch"/>
        <view:CountriesDetailsView x:Key="CountriesDetails"/>
    </ResourceDictionary>
</UserControl.Resources>
<Grid>
    <DockPanel>
        <dxr:RibbonControl x:Name="ribbonMain" DockPanel.Dock="Top" RibbonStyle="Office2007" ApplicationButtonLargeIcon="/Images/icon.png" SelectedPage="{Binding SelectedPage, Mode=OneWayToSource}">
            <dxr:RibbonControl.ApplicationMenu>
                <dxr:ApplicationMenu>
                    <dxb:BarButtonItem x:Name="bbiAbout" Content="About" Glyph="{dx:DXImage Image=Info_16x16.png}" LargeGlyph="{dx:DXImage Image=Info_32x32.png}"/>
                    <dxb:BarButtonItem x:Name="bbiHelp" Content="Help" Glyph="{dx:DXImage Image=Question_16x16.png}" LargeGlyph="{dx:DXImage Image=Question_32x32.png}"/>
                    <dxb:BarButtonItem x:Name="bbiPrint" Content="Print" LargeGlyph="{dx:DXImage Image=Print_32x32.png}" Glyph="{dx:DXImage Image=Print_16x16.png}"/>
                    <dxb:BarSubItem x:Name="bsiExport" Content="Export to..." Glyph="{dx:DXImage Image=Export_32x32.png}" LargeGlyph="{dx:DXImage Image=Export_32x32.png}">
                        <dxb:BarButtonItem x:Name="bbiExportToXlsx" Content="XLSX" Glyph="{dx:DXImage Image=ExportToXLSX_32x32.png}" LargeGlyph="{dx:DXImage Image=ExportToXLSX_32x32.png}"/>
                        <dxb:BarButtonItem x:Name="bbiExportToCsv" Content="CSV" Glyph="{dx:DXImage Image=ExportToCSV_32x32.png}" LargeGlyph="{dx:DXImage Image=ExportToCSV_32x32.png}"/>
                        <dxb:BarButtonItem x:Name="bbiExportToPdf" Content="PDF" Glyph="{dx:DXImage Image=ExportToPDF_32x32.png}" LargeGlyph="{dx:DXImage Image=ExportToPDF_32x32.png}"/>
                    </dxb:BarSubItem>
                </dxr:ApplicationMenu>
            </dxr:RibbonControl.ApplicationMenu>
            <dxr:RibbonDefaultPageCategory>
                <dxr:RibbonPage x:Name="pageActions" Caption="Actions">
                    <dxr:RibbonPageGroup x:Name="rpgActions" Caption="File">
                        <dxb:BarButtonItem x:Name="bbiClose" Content="Close" Glyph="{dx:DXImage Image=Close_32x32.png}" LargeGlyph="{dx:DXImage Image=Close_32x32.png}"/>
                        <dxb:BarItemLinkSeparator/>
                        <dxb:BarButtonItem x:Name="bbiRefresh" Content="Refresh" Glyph="{dx:DXImage Image=Refresh2_32x32.png}" LargeGlyph="{dx:DXImage Image=Refresh2_32x32.png}"/>
                    </dxr:RibbonPageGroup>
                    <dxr:RibbonPageGroup x:Name="rpgEdit" Caption="Edit">
                        <dxb:BarButtonItem x:Name="bbiEdit" Content="Edit" Glyph="{dx:DXImage Image=Edit_32x32.png}" LargeGlyph="{dx:DXImage Image=Edit_32x32.png}"/>
                        <dxb:BarButtonItem x:Name="bbiSave" Content="Save" Glyph="{dx:DXImage Image=Save_32x32.png}" LargeGlyph="{dx:DXImage Image=Save_32x32.png}"/>
                        <dxb:BarButtonItem x:Name="bbiCancel" Content="Cancel" Glyph="{dx:DXImage Image=Cancel_32x32.png}" LargeGlyph="{dx:DXImage Image=Cancel_32x32.png}" IsVisible="False"/>
                        <dxb:BarButtonItem x:Name="bbiClear" Content="Clear" LargeGlyph="{dx:DXImage Image=Clear_32x32.png}" Glyph="{dx:DXImage Image=Clear_16x16.png}"/>
                    </dxr:RibbonPageGroup>
                    <dxr:RibbonPageGroup x:Name="rpgClipboard" Caption="Clipboard">
                        <dxb:BarButtonItem  x:Name="bbiCut" Content="Cut" Glyph="{dx:DXImage Image=Cut_32x32.png}" LargeGlyph="{dx:DXImage Image=Cut_32x32.png}"/>
                        <dxb:BarButtonItem x:Name="bbiCopy" Content="Copy" Glyph="{dx:DXImage Image=Copy_32x32.png}" LargeGlyph="{dx:DXImage Image=Copy_32x32.png}"/>
                        <dxb:BarButtonItem x:Name="bbiPaste" Content="Paste" Glyph="{dx:DXImage Image=Paste_32x32.png}" LargeGlyph="{dx:DXImage Image=Paste_32x32.png}"/>
                    </dxr:RibbonPageGroup>
                    <dxr:RibbonPageGroup x:Name="rpgEntity" Caption="Entity">
                        <dxb:BarButtonItem x:Name="bbiClone" Content="Clone" Glyph="{dx:DXImage Image=Merge_32x32.png}" LargeGlyph="{dx:DXImage Image=Merge_32x32.png}"/>
                        <dxb:BarButtonItem x:Name="bbiInsert" Content="Insert" Glyph="{dx:DXImage Image=Add_32x32.png}" LargeGlyph="{dx:DXImage Image=Add_32x32.png}"/>
                        <dxb:BarButtonItem x:Name="bbiDelete" Content="Delete" Glyph="{dx:DXImage Image=Remove_32x32.png}" LargeGlyph="{dx:DXImage Image=Remove_32x32.png}"/>
                    </dxr:RibbonPageGroup>
                </dxr:RibbonPage>
                <dxr:RibbonPage x:Name="pageSecurity" Caption="Security">
                    <dxr:RibbonPageGroup x:Name="rpgUsersSecurity" Caption="Users Security">
                        <dxb:BarButtonItem x:Name="bbiUsers" Content="Users" Command="{Binding OpenSearchTabCommand}" CommandParameter="{StaticResource UsersSearch}" LargeGlyph="{dx:DXImage Image=User_32x32.png}" Glyph="{dx:DXImage Image=User_16x16.png}"/>
                        <dxb:BarButtonItem x:Name="bbiGroups" Content="Groups" Command="{Binding }" LargeGlyph="{dx:DXImage Image=UserGroup_32x32.png}" Glyph="{dx:DXImage Image=UserGroup_16x16.png}"/>
                    </dxr:RibbonPageGroup>
                </dxr:RibbonPage>
                <dxr:RibbonPage x:Name="pageReferenceTables" Caption="Reference Tables">
                    <dxr:RibbonPageGroup x:Name="rpgShippment" Caption="Shippment">
                        <dxb:BarButtonItem x:Name="bbiVessels" Content="Vessels" LargeGlyph="{dx:DXImage Image=GaugeStyleLinearHorizontal_32x32.png}" Glyph="{dx:DXImage Image=User_16x16.png}"/>
                    </dxr:RibbonPageGroup>
                    <dxr:RibbonPageGroup x:Name="rpgGeographic" Caption="Geographic">
                        <dxb:BarButtonItem x:Name="bbiCountries" Content="Countries" Command="{Binding OpenDetailsTabCommand}" CommandParameter="{StaticResource CountriesDetails}" LargeGlyph="{dx:DXImage Image=Country_32x32.png}" Glyph="{dx:DXImage Image=Country_16x16.png}" />
                        <dxb:BarButtonItem x:Name="bbiRegions" Content="Regions" LargeGlyph="{dx:DXImage Image=ShapeLabels_32x32.png}" Glyph="{dx:DXImage Image=ShapeLabels_16x16.png}" />
                    </dxr:RibbonPageGroup>
                    <dxr:RibbonPageGroup x:Name="rpgOtherTables" Caption="Other">
                        <dxb:BarButtonItem Content="Applications" LargeGlyph="{dx:DXImage Image=CSharp_32x32.png}" Glyph="{dx:DXImage Image=CSharp_16x16.png}"/>
                    </dxr:RibbonPageGroup>
                </dxr:RibbonPage>
                <dxr:RibbonPage Caption="Look &amp; Feel">
                    <dxr:RibbonPageGroup Caption="Theme">
                        <dxb:BarEditItem x:Name="bThemes" Content="Current theme">
                            <dxb:BarEditItem.EditTemplate>
                                <DataTemplate>
                                    <dxe:ComboBoxEdit HorizontalAlignment="Left" Width="200" Margin="0,1"
                            IsTextEditable="False"
                            EditValue="{Binding ApplicationThemeName, Source={x:Static dxthm:GlobalThemeHelper.Instance}}"
                            ValueMember="Name"
                            ItemsSource="{Binding Mode=OneWay, Source={x:Static dx:Theme.Themes}}" 
                            NullText="NONE" />
                                </DataTemplate>
                            </dxb:BarEditItem.EditTemplate>
                        </dxb:BarEditItem>
                    </dxr:RibbonPageGroup>
                </dxr:RibbonPage>
            </dxr:RibbonDefaultPageCategory>
        </dxr:RibbonControl>
        <dxr:RibbonStatusBarControl DockPanel.Dock="Bottom">
            <dxr:RibbonStatusBarControl.LeftItems>
                <dxb:BarStaticItem x:Name="biRow" Content="Row:" ShowBorder="False"/>
                <dxb:BarStaticItem x:Name="biRowValue" Content="1"/>
                <dxb:BarStaticItem x:Name="biColumn" Content="Column:" ShowBorder="False"/>
                <dxb:BarStaticItem x:Name="biColumnValue" Content="1"/>
            </dxr:RibbonStatusBarControl.LeftItems>
            <dxr:RibbonStatusBarControl.RightItems>
                <dxb:BarCheckItem x:Name="biLeft" Glyph="{dx:DXImage Image=AlignLeft_16x16.png}" GroupIndex="1" IsChecked="True"/>
                <dxb:BarCheckItem x:Name="biCenter" Glyph="{dx:DXImage Image=AlignCenter_16x16.png}" GroupIndex="1"/>
                <dxb:BarCheckItem x:Name="biRight" Glyph="{dx:DXImage Image=AlignRight_16x16.png}" GroupIndex="1"/>
            </dxr:RibbonStatusBarControl.RightItems>
        </dxr:RibbonStatusBarControl>
        <Grid>
            <dxdo:DockLayoutManager x:Name="dockManager">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="ShowingDockHints">
                        <cmd:EventToCommand
                            Command="{Binding ShowingDockHintsCommand}"
                            PassEventArgsToCommand="True" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
                <dxdo:LayoutGroup>
                    <dxdo:DocumentGroup x:Name="documentGroupTabs" CaptionLocation="Bottom" ItemsSource="{Binding Tabs}" SelectedTabIndex="{Binding SelectedTabIndex}" DestroyOnClosingChildren="False">
                        <dxdo:DocumentGroup.Resources>
                            <Style TargetType="cc:SearchTab">
                                <Setter Property="CloseCommand" Value="{Binding CloseTabCommand}"/>
                                <Setter Property="CaptionImage" Value="{dx:DXImage Image=Lookup&amp;Reference_16x16.png}"/>
                            </Style>
                            <Style TargetType="cc:DetailsTab">
                                <Setter Property="CloseCommand" Value="{Binding CloseTabCommand}"/>
                                <Setter Property="CaptionImage" Value="{dx:DXImage Image=Information_16x16.png}"/>
                            </Style>
                        </dxdo:DocumentGroup.Resources>
                    </dxdo:DocumentGroup>
                </dxdo:LayoutGroup>
            </dxdo:DockLayoutManager>
        </Grid>
    </DockPanel>
</Grid>

viewmodel类:

public class MainViewModel : ViewModelBase
{
    private ObservableCollection<ITab> _tabs;
    public ObservableCollection<ITab> Tabs
    {
        get { return _tabs; }
        set { Set(() => Tabs, ref _tabs, value); }
    }

    private int _selectedTabIndex;
    public int SelectedTabIndex
    {
        get { return _selectedTabIndex; }
        set { Set(() => SelectedTabIndex, ref _selectedTabIndex, value); }
    }

    private ObservableCollection<RibbonPage> _pages;
    public ObservableCollection<RibbonPage> Pages
    {
        get { return _pages; }
        set { Set(() => Pages, ref _pages, value); }
    }

    private RibbonPage _selectedPage;
    public RibbonPage SelectedPage
    {
        get { return _selectedPage; }
        set { Set(() => SelectedPage, ref _selectedPage, value); }
    }

    public ICommand OpenSearchTabCommand { get; set; }
    public ICommand OpenDetailsTabCommand { get; set; }
    public ICommand CloseTabCommand { get; set; }
    public ICommand ShowingDockHintsCommand { get; set; }

    public MainViewModel()
    {
        Tabs = new ObservableCollection<ITab>();
        OpenSearchTabCommand = new RelayCommand<UserControl>(content => OpenTab<SearchTab>(content));
        OpenDetailsTabCommand = new RelayCommand<UserControl>(content => OpenTab<DetailsTab>(content));
        ShowingDockHintsCommand = new RelayCommand<ShowingDockHintsEventArgs>(e => OnShowingDockHints(e));
        CloseTabCommand = new RelayCommand<ITab>(tab => CloseTab(tab));
    }

    private void OnShowingDockHints(ShowingDockHintsEventArgs e)
    {
        e.DisableAll();
        foreach (DockGuide guide in Enum.GetValues(typeof(DockGuide)))
        {
            if (guide != DockGuide.Bottom)
                e.Hide(guide);
        }
    }

    private void OpenTab<T>(UserControl view) where T : ITab, new()
    {
        Tabs.Add(new T() { Caption = view.GetType().Name + new Random().Next().ToString(), Content = view });
        SelectedTabIndex = Tabs.Count - 1;
    }

    private void CloseTab(ITab tab)
        => Tabs.Remove(tab);
}

1 个答案:

答案 0 :(得分:0)

由于您没有要绑定的命令参数属性,我能想到的唯一解决方案如下:

跳过参数,然后将选定的选项卡绑定到viewmodel中的属性。然后,当调用该命令时,您将从该属性而不是命令参数中获取选项卡实例。