通过方法添加选项卡时不显示选项卡



我有一个数据网格。我想添加制表符时,行双击事件上升。当AddTab方法被调用时,Tab被添加到ObservableCollection,但它不显示在TabControl上。为什么它没有出现?因为有一个错误的DataContext当方法调用?

      <DataGrid  helpers:RowDoubleClickHandler.MethodName="AddTab" AutoGenerateColumns="False" 
        IsSynchronizedWithCurrentItem="True" CanUserResizeRows="True" x:Name="dataGrid1" 
        ItemsSource="{Binding DataGridEntries3}" HorizontalContentAlignment="Stretch"
        VerticalContentAlignment="Stretch" IsReadOnly="True">

ViewModel中的AddTab方法

 public void AddTab()
    {
        Tabs.Add(new TabEntry
        {
            Description = "Tab3",
            DataGridEntries = new ObservableCollection<DataGridEntry>()
            {
                new DataGridEntry()
                {
                }
            }
        });
XAML with TabControl
<Window x:Class="ProjectZero.MainWindow"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="clr-namespace:ProjectZero"
Title="MainWindow" Height="350" Width="525" DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Window.Resources>
    <vm:MainViewModel x:Key="ViewModel"/>
</Window.Resources>
<Grid>
    <ToolBar Height="40" VerticalAlignment="Top">
        <Menu>
            <MenuItem Header="Menu" Margin="6" Foreground="White" FontSize="14" FontFamily="Times New Roman">
                <MenuItem Header="Add Invoice" Command="{Binding AddInvoice}"/>
                <MenuItem Header="Invoices List" Command="{Binding AddInvoiceList}" FontFamily="Tahoma" />
            </MenuItem>
            <Menu.Background>
                <SolidColorBrush />
            </Menu.Background>
        </Menu>
        <ToolBar.Background>
            <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
                <GradientStop Color="Black" Offset="0" />
                <GradientStop Color="#FF173ADE" Offset="0.431" />
                <GradientStop Color="#FF0B1D6F" Offset="0.646" />
            </LinearGradientBrush>
        </ToolBar.Background>
    </ToolBar>
    <TabControl x:Name="tabControl1" SelectedItem="{Binding SelectedItem}" ItemsSource="{Binding Tabs}" ItemTemplate="{DynamicResource DataTemplateType1}" TabStripPlacement="Top" HorizontalAlignment="Stretch" Margin="10,46,0,0" VerticalAlignment="Stretch" Width="Auto">
    </TabControl>

ViewModel for Tabs

public class MainViewModel : BaseViewModel
    {
        public RelayCommand RelayCommand { get; set; }
        public MainViewModel()
        {
            this.RelayCommand = new RelayCommand(this);
            Tabs.CollectionChanged += (o, e) =>
            {
                if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
                {
                    foreach (BaseViewModel item in e.NewItems)
                        if (item.MyType == "TabEntry")
                            DataGridEntries3.Add(item as TabEntry);
                }
            };
            var t = (from i in Tabs where i.MyType == "TabEntry" select (TabEntry)i);
            DataGridEntries3 = new ObservableCollection<TabEntry>(t);
        }
        private ObservableCollection<BaseViewModel> _tabs;
        public ObservableCollection<BaseViewModel> Tabs
        {
            get { return _tabs != null ? _tabs : _tabs = new ObservableCollection<BaseViewModel>(); }
            set { _tabs = value; OnPropertyChanged("Tabs"); }
        }
        BaseViewModel _SelectedItem;
        public BaseViewModel SelectedItem
        {
            get { return _SelectedItem; }
            set { _SelectedItem = value; OnPropertyChanged("SelectedItem"); }
        }
private ObservableCollection<TabEntry> _DataGridEntries3;
            public ObservableCollection<TabEntry> DataGridEntries3
            {
        get { return _DataGridEntries3 != null ? _DataGridEntries3 : _DataGridEntries3 = new ObservableCollection<TabEntry>(); }
        set { _DataGridEntries3 = value; OnPropertyChanged("DataGridEntries3"); }
    }
        ICommand _AddInvoice = null;
        ICommand _AddInvoiceList = null;
        public ICommand AddInvoice
        {
            get
            {
                return _AddInvoice != null ? _AddInvoice : _AddInvoice.SetCommand(param =>
                {
                    Tabs.Add(new TabEntry
                    {
                        Description = "Tab3",
                        DataGridEntries = new ObservableCollection<DataGridEntry>()
                {
                    new DataGridEntry()
                    {
                    }
                }
                    });
                });
            }
        }
        public ICommand AddInvoiceList
        {
            get
            {
                return _AddInvoiceList != null ? _AddInvoiceList : _AddInvoiceList.SetCommand(param =>
                {
                    var tab_dc = Tabs.FirstOrDefault(it => it.GetType() == typeof(MainViewModel));
                    if (tab_dc != null)
                    {
                        Tabs.Add(tab_dc);
                    }
                    else
                    {
                        var new_tab = new MainViewModel();
                        Tabs.Add(new_tab);
                    }
                });
            }
        }
    }

还有RowDoubleClick事件处理程序

public sealed class RowDoubleClickHandler : FrameworkElement
    {
        public RowDoubleClickHandler(DataGrid dataGrid)
        {
            MouseButtonEventHandler handler = (sender, args) =>
            {
                var row = sender as DataGridRow;
                if (row != null && row.IsSelected)
                {
                    var methodName = GetMethodName(dataGrid);
                    var dataContextType = dataGrid.DataContext.GetType();
                    var method = dataContextType.GetMethod(methodName);
                    if (method == null)
                    {
                        throw new MissingMethodException(methodName);
                    }
                    method.Invoke(dataGrid.DataContext, null);
                }
            };
            dataGrid.LoadingRow += (s, e) =>
            {
                e.Row.MouseDoubleClick += handler;
            };
            dataGrid.UnloadingRow += (s, e) =>
            {
                e.Row.MouseDoubleClick -= handler;
            };
        }
        public static string GetMethodName(DataGrid dataGrid)
        {
            return (string)dataGrid.GetValue(MethodNameProperty);
        }
        public static void SetMethodName(DataGrid dataGrid, string value)
        {
            dataGrid.SetValue(MethodNameProperty, value);
        }
        public static readonly DependencyProperty MethodNameProperty = DependencyProperty.RegisterAttached(
            "MethodName",
            typeof(string),
            typeof(RowDoubleClickHandler),
            new PropertyMetadata((o, e) =>
            {
                var dataGrid = o as DataGrid;
                if (dataGrid != null)
                {
                    new RowDoubleClickHandler(dataGrid);
                }
            }));
    }

鉴于您在评论中提出的问题,以下是一些建议:

:

    private ObservableCollection<BaseViewModel> _tabs;
    public ObservableCollection<BaseViewModel> Tabs
    {
        get { return _tabs != null ? _tabs : _tabs = new ObservableCollection<BaseViewModel>(); }
        set { _tabs = value; OnPropertyChanged("Tabs"); }
    }

可以重写为:

public ObservableCollection<BaseViewModel> Tabs { get; private set; }

添加到构造函数中:

Tabs = new ObservableCollection<BaseViewModel>();

在您的代码中这是一个一致的主题。基本上,不要修改你的属性getter/setter,除非你真的真的需要。而在你的情况下,它所做的只是使事情复杂化。

当你有一个getter,它会在第一次调用时向你的选项卡集合中添加一个选项卡时,这尤其令人困惑。这在编程上很难理解。只要像其他人一样在构造函数中进行初始化即可:)

相关内容

  • 没有找到相关文章

最新更新