Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.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
Wpf 如何使用列定义。是否正确添加?_Wpf_Xaml - Fatal编程技术网

Wpf 如何使用列定义。是否正确添加?

Wpf 如何使用列定义。是否正确添加?,wpf,xaml,Wpf,Xaml,我从第5章“WPF 4.5释放版”中复制了一个关于dock panel的示例。在本例中,dock设置在网格的右侧,因此在代码隐藏layer0.ColumnDefinitions.Add(column1CloneForLayer0)中时时,将在网格右侧创建内容为column1CloneForLayer0的列。 在我的项目中,我几乎做了同样的事情,但是当我调用函数来添加包含某些内容的列时,在右侧创建了一些空白。。这与预期不符。那么正确的做法是什么呢? 1.如何在网格左侧添加列 2.在本例中,列已创

我从第5章“WPF 4.5释放版”中复制了一个关于dock panel的示例。在本例中,dock设置在网格的右侧,因此在代码隐藏
layer0.ColumnDefinitions.Add(column1CloneForLayer0)中时时,将在网格右侧创建内容为column1CloneForLayer0
的列。

在我的项目中,我几乎做了同样的事情,但是当我调用函数来添加包含某些内容的列时,在右侧创建了一些空白。。这与预期不符。那么正确的做法是什么呢?
1.如何在网格左侧添加列

2.在本例中,列已创建,但为什么为空?也许我需要设置Z索引

更新 我在书中的原始示例中添加了一些类似的内容,得到了错误的结果。下面是源代码。我刚刚在左边添加了一个
leftToolBox

更新2 相关代码:在这种情况下,我只需在左侧添加一个带有按钮的stackpanel,然后单击调用
DocakPane(3)
,而不是在左侧提供新列,而是在右侧创建列

public void DockPane(int paneNumber)
{
    if (paneNumber == 1)
    {
        pane1Button.Visibility = Visibility.Collapsed;
        pane1PinImage.Source = new BitmapImage(new Uri("pin.gif", UriKind.Relative));

        // Add the cloned column to layer 0:
        layer0.ColumnDefinitions.Add(column1CloneForLayer0);
        // Add the cloned column to layer 1, but only if pane 2 is docked:
        if (pane2Button.Visibility == Visibility.Collapsed) layer1.ColumnDefinitions.Add(column2CloneForLayer1);
    }
    else if (paneNumber == 2)
    {
        pane2Button.Visibility = Visibility.Collapsed;
        pane2PinImage.Source = new BitmapImage(new Uri("pin.gif", UriKind.Relative));

        // Add the cloned column to layer 0:
        layer0.ColumnDefinitions.Add(column2CloneForLayer0);
        // Add the cloned column to layer 1, but only if pane 1 is docked:
        if (pane1Button.Visibility == Visibility.Collapsed) layer1.ColumnDefinitions.Add(column2CloneForLayer1);
    }
    else
    {
        leftpane1Button.Visibility = Visibility.Collapsed;
        pane3PinImage.Source = new BitmapImage(new Uri("pin.gif", UriKind.Relative));
        layer0.ColumnDefinitions.Add(testcol);

    }
}

基于提供的示例项目,下面是使用MVVM对其进行的重写,与硬编码相关的大部分问题都将消失。它不是纯粹的MVVM,但它主要是MVVM

首先定义ViewModels

表示停靠窗格的类

class DockablePaneVM : ViewModelBase
{
    public DockablePaneVM(DockHostVM host)
    {
        Host = host;
    }

    private string _title;
    public string Title
    {
        get { return _title; }
        set
        {
            _title = value;
            RaisePropertyChanged("Title");
        }
    }

    private bool _isPinned;
    public bool IsPinned
    {
        get { return _isPinned; }
        set
        {
            _isPinned = value;
            Host.PinModeChanged(this);
            RaisePropertyChanged("IsPinned");
        }
    }

    private object _content;
    public object Content
    {
        get { return _content; }
        set
        {
            _content = value;
            RaisePropertyChanged("Content");
        }
    }

    public DockHostVM Host { get; private set; }
    public Dock Dock { get; set; }
}
作为dockpanes的主机,我使用collectionview简化了位置

class DockHostVM : ViewModelBase
{
    public DockHostVM()
    {
        Panes = new ObservableCollection<DockablePaneVM>();
        LeftPanes = new CollectionViewSource() { Source = Panes }.View;
        RightPanes = new CollectionViewSource() { Source = Panes }.View;
        FlotingLeftPanes = new CollectionViewSource() { Source = Panes }.View;
        FlotingRightPanes = new CollectionViewSource() { Source = Panes }.View;

        LeftPanes.Filter = o => Filter(o, Dock.Left, true);
        RightPanes.Filter = o => Filter(o, Dock.Right, true);
        FlotingLeftPanes.Filter = o => Filter(o, Dock.Left, false);
        FlotingRightPanes.Filter = o => Filter(o, Dock.Right, false);
    }
    private bool Filter(object obj, Dock dock, bool isPinned)
    {
        DockablePaneVM vm = obj as DockablePaneVM;
        return vm.Dock == dock && vm.IsPinned == isPinned;
    }

    public ObservableCollection<DockablePaneVM> Panes { get; set; }

    public ICollectionView LeftPanes { get; set; }
    public ICollectionView RightPanes { get; set; }

    public ICollectionView FlotingLeftPanes { get; set; }
    public ICollectionView FlotingRightPanes { get; set; }

    private object _content;

    public object Content
    {
        get { return _content; }
        set { _content = value; }
    }

    public void PinModeChanged(DockablePaneVM paneVM)
    {
        LeftPanes.Refresh();
        RightPanes.Refresh();
        FlotingLeftPanes.Refresh();
        FlotingRightPanes.Refresh();
    }

    //sample generator
    public static DockHostVM GetSample()
    {
        DockHostVM vm = new DockHostVM();
        vm.Panes.Add(new DockablePaneVM(vm) { Title = "Left Toolbox", Content = new ToolBoxVM() });
        vm.Panes.Add(new DockablePaneVM(vm) { Title = "Solution Explorer", Content = new SolutionExplorerVM(), Dock = Dock.Right });
        vm.Panes.Add(new DockablePaneVM(vm) { Title = "Toolbox", Content = new ToolBoxVM(), Dock = Dock.Right });
        return vm;
    }
}
类DockHostVM:ViewModelBase
{
公共DockHostVM()
{
窗格=新的可观察集合();
LeftPanes=new CollectionViewSource(){Source=Panes}.View;
RightPanes=new CollectionViewSource(){Source=Panes}.View;
FlotingLeftPanes=new CollectionViewSource(){Source=Panes}.View;
FlotingRightPanes=new CollectionViewSource(){Source=Panes}.View;
LeftPanes.Filter=o=>Filter(o,Dock.Left,true);
RightPanes.Filter=o=>Filter(o,Dock.Right,true);
FlotingLeftPanes.Filter=o=>Filter(o,Dock.Left,false);
FlotingRightPanes.Filter=o=>Filter(o,Dock.Right,false);
}
专用布尔过滤器(对象对象对象、Dock Dock、布尔Ispined)
{
DockablePaneVM vm=obj作为DockablePaneVM;
返回vm.Dock==Dock&&vm.IsPinned==IsPinned;
}
公共可观察集合窗格{get;set;}
公共ICollectionView左窗格{get;set;}
公共ICollectionView右窗格{get;set;}
公共ICollectionView浮动左窗格{get;set;}
public ICollectionView FlotingRightPanes{get;set;}
私有对象内容;
公共对象内容
{
获取{return\u content;}
设置{u content=value;}
}
公共无效PinModeChanged(DockablePaneVM paneVM)
{
LeftPanes.Refresh();
右窗格。刷新();
FlotingLeftPanes.Refresh();
FlotingRightPanes.Refresh();
}
//样品发生器
公共静态DockHostVM GetSample()
{
DockHostVM=新的DockHostVM();
添加(新的DockablePaneVM(vm){Title=“Left Toolbox”,Content=new ToolBoxVM()});
添加(new-DockablePaneVM(vm){Title=“解决方案浏览器”,Content=new-SolutionExplorerVM(),Dock=Dock.Right});
添加(新的DockablePaneVM(vm){Title=“Toolbox”,Content=newtoolboxvm(),Dock=Dock.Right});
返回虚拟机;
}
}
然后是样式,以提供类的视图

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:l="clr-namespace:VisualStudioLikePanes">

    <DataTemplate DataType="{x:Type l:DockablePaneVM}">
        <Grid Grid.Column="1">
            <Grid.RowDefinitions>
                <RowDefinition Height="auto" />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition Width="auto" />
            </Grid.ColumnDefinitions>
            <TextBlock Padding="8,4"
                       Text="{Binding Title}"
                       TextTrimming="CharacterEllipsis"
                       Background="{DynamicResource {x:Static SystemColors.ActiveCaptionBrushKey}}"
                       Foreground="{DynamicResource {x:Static SystemColors.ActiveCaptionTextBrushKey}}" />
            <ToggleButton IsChecked="{Binding IsPinned}"
                          Grid.Column="1">
                <Image Name="pinImage"
                       Source="pinHorizontal.gif" />
            </ToggleButton>
            <ContentControl Content="{Binding Content}"
                            Grid.Row="1"
                            Grid.ColumnSpan="2" />
        </Grid>
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding IsPinned}"
                         Value="True">
                <Setter Property="Source"
                        TargetName="pinImage"
                        Value="pin.gif" />
            </DataTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>

    <Style TargetType="TabItem">
        <Setter Property="Header"
                Value="{Binding Title}" />
    </Style>

    <Style TargetType="TabItem"
           x:Key="FloterItem"
           BasedOn="{StaticResource {x:Type TabItem}}">
        <Setter Property="LayoutTransform">
            <Setter.Value>
                <RotateTransform Angle="90" />
            </Setter.Value>
        </Setter>
    </Style>

    <Style TargetType="TabControl">
        <Setter Property="l:TabControlHelper.IsLastItemSelected"
                Value="True" />
        <Style.Triggers>
            <Trigger Property="HasItems"
                     Value="false">
                <Setter Property="Visibility"
                        Value="Collapsed" />
            </Trigger>
        </Style.Triggers>
    </Style>

    <Style TargetType="TabControl"
           x:Key="AutoResizePane"
           BasedOn="{StaticResource {x:Type TabControl}}">
        <Style.Triggers>
            <Trigger Property="IsMouseOver"
                     Value="false">
                <Setter Property="Width"
                        Value="23" />
            </Trigger>
        </Style.Triggers>
    </Style>

    <DataTemplate DataType="{x:Type l:ToolBoxVM}">
        <ListBox Padding="10"
                 Grid.Row="1">
            <ListBoxItem>Button</ListBoxItem>
            <ListBoxItem>CheckBox</ListBoxItem>
            <ListBoxItem>ComboBox</ListBoxItem>
            <ListBoxItem>Label</ListBoxItem>
            <ListBoxItem>ListBox</ListBoxItem>
        </ListBox>
    </DataTemplate>

    <DataTemplate DataType="{x:Type l:SolutionExplorerVM}">
        <TreeView Grid.Row="2">
            <TreeViewItem Header="My Solution" IsExpanded="True">
                <TreeViewItem Header="Project #1" />
                <TreeViewItem Header="Project #2" />
                <TreeViewItem Header="Project #3" />
            </TreeViewItem>
        </TreeView>
    </DataTemplate>
</ResourceDictionary>

按钮
复选框
组合框
标签
列表框
我还创建了一些虚拟类来表示工具箱和解决方案资源管理器

这也是一个帮助类,用于提高我用来托管dockpanes的选项卡控件的可用性

class TabControlHelper
{
    public static bool GetIsLastItemSelected(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsLastItemSelectedProperty);
    }

    public static void SetIsLastItemSelected(DependencyObject obj, bool value)
    {
        obj.SetValue(IsLastItemSelectedProperty, value);
    }

    // Using a DependencyProperty as the backing store for IsLastItemSelected.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsLastItemSelectedProperty =
        DependencyProperty.RegisterAttached("IsLastItemSelected", typeof(bool), typeof(TabControlHelper), new PropertyMetadata(false, OnIsLastItemSelected));

    private static void OnIsLastItemSelected(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        TabControl tc = d as TabControl;
        tc.Items.CurrentChanged += (ss, ee) =>
        {
            if (tc.SelectedIndex < 0 && tc.Items.Count > 0)
                tc.SelectedIndex = 0;
        };

    }
}
类TabControlHelper
{
公共静态bool GetIsLastItemSelected(DependencyObject obj)
{
返回(bool)对象GetValue(IsLastItemSelectedProperty);
}
公共静态void SetIsLastItemSelected(DependencyObject对象,布尔值)
{
obj.SetValue(IsLastItemSelectedProperty,值);
}
//使用DependencyProperty作为IsLastItemSelected的后备存储。这将启用动画、样式、绑定等。。。
public static readonly dependencProperty IsLastItemSelectedProperty=
DependencyProperty.RegisterAttached(“IsLastItemSelected”、typeof(bool)、typeof(TabControlHelper)、new PropertyMetadata(false、OnIsLastItemSelected));
已选择专用静态void onislatimes(DependencyObject d、DependencyPropertyChangedEventArgs e)
{
TabControl tc=d作为TabControl;
tc.Items.CurrentChanged+=(ss,ee)=>
{
如果(tc.SelectedIndex<0&&tc.Items.Count>0)
tc.SelectedIndex=0;
};
}
}
这将使项目随时处于选中状态,在此项目中,固定/取消固定停靠窗格时将使用该项目

现在是主窗口,请注意,我已经将停靠窗格限定为4个选项卡控件,左、右、左浮动和右浮动

<Window x:Class="VisualStudioLikePanes.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        Height="500"
        Width="800"
        WindowStartupLocation="CenterScreen"
        xmlns:l="clr-namespace:VisualStudioLikePanes">
    <Window.DataContext>
        <ObjectDataProvider MethodName="GetSample"
                            ObjectType="{x:Type l:DockHostVM}" />
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Menu>
            <MenuItem Header="FILE" />
             ...
            <MenuItem Header="HELP" />
        </Menu>
        <DockPanel LastChildFill="True"
                   Grid.Row="1">

            <Border Width="23"
                    DockPanel.Dock="Left"
                    Visibility="{Binding Visibility, ElementName=LeftFloter}" />
            <Border Width="23"
                    DockPanel.Dock="Right"
                    Visibility="{Binding Visibility, ElementName=RightFloter}" />

            <TabControl ItemsSource="{Binding LeftPanes}"
                        DockPanel.Dock="Left" />

            <TabControl ItemsSource="{Binding RightPanes}"
                        DockPanel.Dock="Right" />

            <Grid Name="layer0">
                ... page content
            </Grid>
        </DockPanel>
        <TabControl ItemsSource="{Binding FlotingLeftPanes}"
                    Grid.Row="1"
                    HorizontalAlignment="Left"
                    TabStripPlacement="Left"
                    Style="{StaticResource AutoResizePane}"
                    ItemContainerStyle="{StaticResource FloterItem}"
                    x:Name="LeftFloter" />

        <TabControl ItemsSource="{Binding FlotingRightPanes}"
                    Grid.Row="1"
                    HorizontalAlignment="Right"
                    TabStripPlacement="Right"
                    Style="{StaticResource AutoResizePane}"
                    ItemContainerStyle="{StaticResource FloterItem}"
                    x:Name="RightFloter" />
    </Grid>
</Window>

...