|  | @@ -359,7 +359,8 @@ namespace InABox.DynamicGrid
 | 
	
		
			
				|  |  |          private readonly Button Print;
 | 
	
		
			
				|  |  |          private readonly Label PrintSpacer;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        private readonly StackPanel Stack;
 | 
	
		
			
				|  |  | +        private readonly StackPanel LeftButtonStack;
 | 
	
		
			
				|  |  | +        private readonly StackPanel RightButtonStack;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          private readonly DynamicRowMovementColumn? up;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -371,7 +372,9 @@ namespace InABox.DynamicGrid
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          public event OnCellDoubleClick? OnCellDoubleClick;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        public OnGridChanged? OnChanged;
 | 
	
		
			
				|  |  | +        public event OnGridChanged? OnChanged;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        public void DoChanged() => OnChanged?.Invoke(this);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          public event EditorValueChangedHandler? OnEditorValueChanged;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -540,30 +543,34 @@ namespace InABox.DynamicGrid
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              ExportSpacer = new Label { Width = 5 };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            Stack = new StackPanel();
 | 
	
		
			
				|  |  | -            Stack.Orientation = Orientation.Horizontal;
 | 
	
		
			
				|  |  | -            Stack.SetValue(DockPanel.DockProperty, Dock.Left);
 | 
	
		
			
				|  |  | +            LeftButtonStack = new StackPanel();
 | 
	
		
			
				|  |  | +            LeftButtonStack.Orientation = Orientation.Horizontal;
 | 
	
		
			
				|  |  | +            LeftButtonStack.SetValue(DockPanel.DockProperty, Dock.Left);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            Stack.Children.Add(Help);
 | 
	
		
			
				|  |  | -            Stack.Children.Add(Add);
 | 
	
		
			
				|  |  | -            Stack.Children.Add(Edit);
 | 
	
		
			
				|  |  | +            LeftButtonStack.Children.Add(Help);
 | 
	
		
			
				|  |  | +            LeftButtonStack.Children.Add(Add);
 | 
	
		
			
				|  |  | +            LeftButtonStack.Children.Add(Edit);
 | 
	
		
			
				|  |  |              //Stack.Children.Add(MultiEdit);
 | 
	
		
			
				|  |  | -            Stack.Children.Add(EditSpacer);
 | 
	
		
			
				|  |  | +            LeftButtonStack.Children.Add(EditSpacer);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            Stack.Children.Add(Print);
 | 
	
		
			
				|  |  | -            Stack.Children.Add(PrintSpacer);
 | 
	
		
			
				|  |  | +            LeftButtonStack.Children.Add(Print);
 | 
	
		
			
				|  |  | +            LeftButtonStack.Children.Add(PrintSpacer);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            Stack.Children.Add(Cut);
 | 
	
		
			
				|  |  | -            Stack.Children.Add(Copy);
 | 
	
		
			
				|  |  | -            Stack.Children.Add(Paste);
 | 
	
		
			
				|  |  | -            Stack.Children.Add(ClipboardSpacer);
 | 
	
		
			
				|  |  | +            LeftButtonStack.Children.Add(Cut);
 | 
	
		
			
				|  |  | +            LeftButtonStack.Children.Add(Copy);
 | 
	
		
			
				|  |  | +            LeftButtonStack.Children.Add(Paste);
 | 
	
		
			
				|  |  | +            LeftButtonStack.Children.Add(ClipboardSpacer);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            Stack.Children.Add(Export);
 | 
	
		
			
				|  |  | -            Stack.Children.Add(Import);
 | 
	
		
			
				|  |  | -            Stack.Children.Add(ExportSpacer);
 | 
	
		
			
				|  |  | +            LeftButtonStack.Children.Add(Export);
 | 
	
		
			
				|  |  | +            LeftButtonStack.Children.Add(Import);
 | 
	
		
			
				|  |  | +            LeftButtonStack.Children.Add(ExportSpacer);
 | 
	
		
			
				|  |  | +            
 | 
	
		
			
				|  |  | +            RightButtonStack = new StackPanel();
 | 
	
		
			
				|  |  | +            RightButtonStack.Orientation = Orientation.Horizontal;
 | 
	
		
			
				|  |  | +            RightButtonStack.SetValue(DockPanel.DockProperty, Dock.Right);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              Delete = CreateButton(Properties.Resources.delete.AsBitmapImage(Color.White));
 | 
	
		
			
				|  |  | -            Delete.Margin = new Thickness(0, 2, 0, 0);
 | 
	
		
			
				|  |  | +            Delete.Margin = new Thickness(2, 2, 0, 0);
 | 
	
		
			
				|  |  |              Delete.SetValue(DockPanel.DockProperty, Dock.Right);
 | 
	
		
			
				|  |  |              Delete.Click += Delete_Click;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -580,8 +587,9 @@ namespace InABox.DynamicGrid
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              Docker.SetValue(Grid.RowProperty, 2);
 | 
	
		
			
				|  |  |              Docker.SetValue(Grid.ColumnProperty, 0);
 | 
	
		
			
				|  |  | -            Docker.Children.Add(Stack);
 | 
	
		
			
				|  |  | +            Docker.Children.Add(LeftButtonStack);
 | 
	
		
			
				|  |  |              Docker.Children.Add(Delete);
 | 
	
		
			
				|  |  | +            Docker.Children.Add(RightButtonStack);
 | 
	
		
			
				|  |  |              Docker.Children.Add(Count);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1189,6 +1197,8 @@ namespace InABox.DynamicGrid
 | 
	
		
			
				|  |  |              var visualContainer = DataGrid.GetVisualContainer();
 | 
	
		
			
				|  |  |              var rowcolumnindex = visualContainer.PointToCellRowColumnIndex(e.GetPosition(visualContainer));
 | 
	
		
			
				|  |  |              var columnindex = DataGrid.ResolveToGridVisibleColumnIndex(rowcolumnindex.ColumnIndex);
 | 
	
		
			
				|  |  | +            if ((columnindex < 0) || (columnindex >= ColumnList.Count))
 | 
	
		
			
				|  |  | +                return;
 | 
	
		
			
				|  |  |              var column = ColumnList[columnindex] as DynamicActionColumn;
 | 
	
		
			
				|  |  |              var rowindex = rowcolumnindex.RowIndex - (Options.Contains(DynamicGridOption.FilterRows) ? 2 : 1);
 | 
	
		
			
				|  |  |              if (rowindex < 0)
 | 
	
	
		
			
				|  | @@ -1421,8 +1431,9 @@ namespace InABox.DynamicGrid
 | 
	
		
			
				|  |  |                          newcol.ImageWidth = DataGrid.RowHeight - 8;
 | 
	
		
			
				|  |  |                          newcol.ColumnSizer = GridLengthUnitType.None;
 | 
	
		
			
				|  |  |                          newcol.HeaderText = column.HeaderText;
 | 
	
		
			
				|  |  | +                        newcol.AllowSorting = false;
 | 
	
		
			
				|  |  |                          
 | 
	
		
			
				|  |  | -                        ApplyFilterStyle(newcol, true);
 | 
	
		
			
				|  |  | +                        ApplyFilterStyle(newcol, true, true);
 | 
	
		
			
				|  |  |                          
 | 
	
		
			
				|  |  |                          newcol.ShowToolTip = column.ToolTip != null;
 | 
	
		
			
				|  |  |                          
 | 
	
	
		
			
				|  | @@ -1759,7 +1770,7 @@ namespace InABox.DynamicGrid
 | 
	
		
			
				|  |  |                          : HorizontalAlignment.Right;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                    ApplyFilterStyle(newcol,filtering);
 | 
	
		
			
				|  |  | +                    ApplyFilterStyle(newcol, filtering, false);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                      var headstyle = new Style(typeof(GridHeaderCellControl));
 | 
	
	
		
			
				|  | @@ -1828,7 +1839,7 @@ namespace InABox.DynamicGrid
 | 
	
		
			
				|  |  |              ResizeColumns(DataGrid, DataGrid.ActualWidth - 2, DataGrid.ActualHeight - 2);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        private void ApplyFilterStyle(GridColumn column, bool filtering)
 | 
	
		
			
				|  |  | +        private void ApplyFilterStyle(GridColumn column, bool filtering, bool isactioncolumn)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              var filterstyle = new Style();
 | 
	
		
			
				|  |  |              if (filtering)
 | 
	
	
		
			
				|  | @@ -1839,7 +1850,9 @@ namespace InABox.DynamicGrid
 | 
	
		
			
				|  |  |                  column.FilterRowCondition = FilterRowCondition.Contains;
 | 
	
		
			
				|  |  |                  column.FilterRowOptionsVisibility = Visibility.Collapsed;
 | 
	
		
			
				|  |  |                  column.AllowBlankFilters = true;
 | 
	
		
			
				|  |  | -                column.AllowSorting = CanSort();
 | 
	
		
			
				|  |  | +                column.AllowSorting = isactioncolumn 
 | 
	
		
			
				|  |  | +                    ? false 
 | 
	
		
			
				|  |  | +                    : CanSort();
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  |              else
 | 
	
		
			
				|  |  |              {
 | 
	
	
		
			
				|  | @@ -2745,6 +2758,7 @@ namespace InABox.DynamicGrid
 | 
	
		
			
				|  |  |                  
 | 
	
		
			
				|  |  |                  var item = CreateItem();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +                // Yea, and this won't work, because we're actually usually showing the description of a linked item,
 | 
	
		
			
				|  |  |                  // Yea, and this won't work, because we're actually usually showing the description of a linked item,
 | 
	
		
			
				|  |  |                  // not the id of the link, and we need to set the ID to have it work properly :-(
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -3200,6 +3214,7 @@ namespace InABox.DynamicGrid
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              if (!string.IsNullOrEmpty(text))
 | 
	
		
			
				|  |  |              {
 | 
	
		
			
				|  |  | +                button.MaxWidth = double.MaxValue;
 | 
	
		
			
				|  |  |                  var lbl = new Label();
 | 
	
		
			
				|  |  |                  lbl.Content = text;
 | 
	
		
			
				|  |  |                  lbl.VerticalAlignment = VerticalAlignment.Stretch;
 | 
	
	
		
			
				|  | @@ -3208,6 +3223,8 @@ namespace InABox.DynamicGrid
 | 
	
		
			
				|  |  |                  lbl.ToolTip = ToolTip;
 | 
	
		
			
				|  |  |                  stackPnl.Children.Add(lbl);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | +            else
 | 
	
		
			
				|  |  | +                button.MaxWidth = 30;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              button.Content = stackPnl;
 | 
	
		
			
				|  |  |              button.ToolTip = tooltip;
 | 
	
	
		
			
				|  | @@ -3229,21 +3246,28 @@ namespace InABox.DynamicGrid
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        public Button AddButton(string caption, BitmapImage? image, string? tooltip, Func<Button, CoreRow[], bool> action)
 | 
	
		
			
				|  |  | +        public override Button AddButton(string caption, BitmapImage? image, string? tooltip, Func<Button, CoreRow[], bool> action, DynamicGridButtonPosition position = DynamicGridButtonPosition.Left)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  |              var button = CreateButton(image, caption, tooltip);
 | 
	
		
			
				|  |  | -            button.Margin = new Thickness(bFirstButtonAdded && AnyButtonsVisible() ? /* 10 */ 0 : 0, 2, 2, 0);
 | 
	
		
			
				|  |  | -            button.Padding = new Thickness(5, 0, 5, 0);
 | 
	
		
			
				|  |  | +            button.Margin = position == DynamicGridButtonPosition.Right
 | 
	
		
			
				|  |  | +                ? new Thickness(2, 2, 0, 0)
 | 
	
		
			
				|  |  | +                : bFirstButtonAdded && AnyButtonsVisible() 
 | 
	
		
			
				|  |  | +                    ? new Thickness(0, 2, 0, 0)
 | 
	
		
			
				|  |  | +                    : new Thickness(0, 2, 2, 0);
 | 
	
		
			
				|  |  | +            button.Padding = !String.IsNullOrWhiteSpace(caption) ? new Thickness(5, 1, 5, 1) : new Thickness(1);
 | 
	
		
			
				|  |  |              button.Tag = action;
 | 
	
		
			
				|  |  |              button.Click += Button_Click;
 | 
	
		
			
				|  |  | -            Stack.Children.Add(button);
 | 
	
		
			
				|  |  | +            if (position == DynamicGridButtonPosition.Right)
 | 
	
		
			
				|  |  | +                RightButtonStack.Children.Add(button);
 | 
	
		
			
				|  |  | +            else
 | 
	
		
			
				|  |  | +                LeftButtonStack.Children.Add(button);
 | 
	
		
			
				|  |  |              bFirstButtonAdded = false;
 | 
	
		
			
				|  |  |              return button;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        public Button AddButton(string caption, BitmapImage? image, Func<Button, CoreRow[], bool> action)
 | 
	
		
			
				|  |  | +        public Button AddButton(string caption, BitmapImage? image, Func<Button, CoreRow[], bool> action, DynamicGridButtonPosition position = DynamicGridButtonPosition.Left)
 | 
	
		
			
				|  |  |          {
 | 
	
		
			
				|  |  | -            var result = AddButton(caption, image, null, action);
 | 
	
		
			
				|  |  | +            var result = AddButton(caption, image, null, action, position);
 | 
	
		
			
				|  |  |              return result;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 |