Pass Parameters to Tap Gesture Xamarin Forms - c#

I am trying to pass parameters from a page to another page. These passed parameters will be used to select from an SQL table.
The page is built as follows: (The code behind)
private MainRoutePageViewModel mainroutepageviewmodel;
private List<RouteInfo> routeinfo;
Constructor:
public MainRoutePageViewDetail(MessagDatabase database)
{
InitializeComponent();
BindingContext = mainroutepageviewmodel = new MainRoutePageViewModel(database,Navigation);
//_listOfProperties = mainroutepageviewmodel.GetLabelInfo();
ScrollView scrollview = new ScrollView();
StackLayout mainstack = new StackLayout();
mainstack.Spacing = 0;
mainstack.Padding = 0;
//mainstack.HeightRequest = 2000;
routeinfo = mainroutepageviewmodel.GetLabelInfo();
string _routePlacer = "";
foreach (var i in routeinfo)
{
mainstack.Children.Add(NewRouteName(i.RouteName));
mainstack.Children.Add(BuildNewRoute(i.RouteStops,i));
_routePlacer = i.RouteName;
}
scrollview.Content = mainstack;
Content = scrollview;
}// end of constructor
The BuildNewRoute method:
public StackLayout BuildNewRoute(List<string> location, RouteInfo routeinfo)
{
StackLayout stackLayout = new StackLayout();
//stackLayout.HeightRequest = 1000;
foreach (var i in location) {
StackLayout stackLayout2 = new StackLayout();
stackLayout2.HeightRequest = 200;
Grid grid = new Grid();
grid.ColumnSpacing = 0;
grid.RowSpacing = 0;
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(15, GridUnitType.Star) });
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(20, GridUnitType.Star) });
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(20, GridUnitType.Star) });
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(20, GridUnitType.Star) });
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(20, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(55, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(18, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(18, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(18, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(40, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(30, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(10, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(15, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(5, GridUnitType.Star) });
TapGestureRecognizer ArrowtapGesture = new TapGestureRecognizer();
ArrowtapGesture.Tapped += ArrowtapGesture_Tapped;
// Arrow icon
Image arrowimage = new Image();
arrowimage.Source = "Resources/arrow.png";
arrowimage.VerticalOptions = LayoutOptions.Center;
arrowimage.HorizontalOptions = LayoutOptions.Center;
arrowimage.GestureRecognizers.Add(ArrowtapGesture);
grid.Children.Add(arrowimage,7,6);
// total weight labels
Label weightlabel = new Label();
weightlabel.Text = "Total Weight [kg]: ";
grid.Children.Add(weightlabel,1,5,3,4);
// total items labels
Label itemsLabel = new Label();
itemsLabel.Text = "Total Items: ";
grid.Children.Add(itemsLabel, 1, 5, 4, 5);
// underline labels
Label firstunderline = new Label();
Label secondunderline = new Label();
firstunderline.BackgroundColor = Color.Black;
secondunderline.BackgroundColor = Color.Black;
grid.Children.Add(firstunderline,0,9,0,1);
grid.Children.Add(secondunderline,0,9,2,3);
// address label
Label labelLocation = new Label();
labelLocation.Text = i;
grid.Children.Add(labelLocation, 0, 3);
//sequence label
Label sequencelable = new Label();
sequencelable.Text = "Sequence: ";
sequencelable.VerticalTextAlignment = TextAlignment.Center;
grid.Children.Add(sequencelable, 0, 1);
// slot label
Label slotlabel = new Label();
slotlabel.Text = "ETA/Slot: ";
slotlabel.VerticalTextAlignment = TextAlignment.Center;
grid.Children.Add(slotlabel,1,4,1,2);
// time label
Label timelabel = new Label();
timelabel.Text = "Time: ";
timelabel.VerticalTextAlignment = TextAlignment.Center;
grid.Children.Add(timelabel, 4, 5,1,2);
// Status label
Label statuslabel = new Label();
statuslabel.Text = "Status: ";
statuslabel.VerticalTextAlignment = TextAlignment.Center;
grid.Children.Add(statuslabel, 5, 6,1,2);
//start button
Button startbutton = new Button();
startbutton.Text = "Pending";
startbutton.BackgroundColor = Color.Gray;
grid.Children.Add(startbutton,5,8,4,6);
// Phone book image
Image bookImage = new Image();
//bookImage.BackgroundColor = Color.White;
bookImage.Source = "Resources/phoneWithBook.png";
bookImage.VerticalOptions = LayoutOptions.Center;
bookImage.HorizontalOptions = LayoutOptions.Center;
grid.Children.Add(bookImage,1,2,6,7);
//Globe image
Image GlobeImage = new Image();
// GlobeImage.BackgroundColor = Color.White;
GlobeImage.Source = "Resources/globe.png";
GlobeImage.VerticalOptions = LayoutOptions.Center;
GlobeImage.HorizontalOptions = LayoutOptions.Center;
grid.Children.Add(GlobeImage, 2, 3, 6, 7);
stackLayout2.Children.Add(grid);
stackLayout.Children.Add(stackLayout2);
}
return stackLayout;
}
As you can probably see it loops through a list of collected data and adds grids and labels to a main StackLayout.
This is not the issue the page building works fine.
What you can see is the arrow icon image that has a tap gesture attached to it. This tap gesture uses the view model to open the next page.
The tap gesture:
private async void ArrowtapGesture_Tapped(object sender, EventArgs e)
{
await mainroutepageviewmodel.OpenStopDetail();
}
And the OpenStopDetail method:
public async Task OpenStopDetail()
{
await Navigation.PushAsync(new StopDetailPageView());
}
I want to know how to pass parameters from the tap event through to the StopDetailView page.
Specifically the text from the sequence label.
Some things I have tried, have been using the casting in the tap event but this seems to be bound to the item that is selected. In other words its giving me access to image properties. Which is no good for my situation.
I cant seem to find a way to access each label property individually to pass as a parameter. Sorry if this isn't clear, it was tough to explain. Let me know if more detail is needed.

You should be able to use the CommandParameter of the TapGestureRecognizer.
In XAML:-
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"
CommandParameter="Value"/>
e.Parameter will be whatever you set in the CommandParameter.
private async void TapGestureRecognizer_Tapped(object sender, TappedEventArgs e)
Edit:
It has been pointed out that the above is not the right signature, the param, needs to be EventArgs and cast to TappedEventArgs.
private async void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
var param = ((TappedEventArgs)e).Parameter;
}

The sender of the Tapped event will be the control the gesture recognizer is attached to - in your case, an Image. So you can add your data to one of the Image's properties in order to access it from your event handler.
// assign parameter to ClassId (must be a string)
arrowimage.ClassId = "blah";
arrowimage.GestureRecognizers.Add(ArrowtapGesture);
private async void ArrowtapGesture_Tapped(object sender, EventArgs e)
{
// retrieve parameter from sender's ClassId
var parm = ((Image)sender).ClassId;
await mainroutepageviewmodel.OpenStopDetail();
}

<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="Share_Tapped" CommandParameter="{Binding .}"/>
</Image.GestureRecognizers>
enter code here
private void Share_Tapped(object sender, TappedEventArgs e)
{
var contact = (e.Parameter) as DetailList;
}
Result

Related

TextBlock doesn't want to adjust grid columns

I'm preparing control to present some data. It is built in the following way:
-> ScrollViewer
--> StackPanel
---> Border
----> Grid
---> Border
----> Grid
...
---> Border
----> Grid
And there is my code for each item
public class PresenterItem : Border
{
// Variables
private Submission submission;
private int index;
private Grid grid = new Grid();
// Constructor
public PresenterItem(int i, Submission subm)
{
index = i;
submission = subm;
Child = grid;
Background = Global.GET_BRUSH("ItemBackground");
CornerRadius = new CornerRadius(5);
Margin = new Thickness(0, 0, 0, 10);
Padding = new Thickness(5);
grid.ShowGridLines = true;
grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(40, GridUnitType.Pixel) });
grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(2, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(2, GridUnitType.Star) });
grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(40, GridUnitType.Pixel) });
grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(30, GridUnitType.Pixel) });
grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
InsertContent();
}
private Label CreateLabel(int row, int column, string content, int columnSpan = 1)
{
Label newLabel = new Label();
newLabel.Content = content;
Grid.SetRow(newLabel, row);
Grid.SetColumn(newLabel, column);
Grid.SetColumnSpan(newLabel, columnSpan);
grid.Children.Add(newLabel);
return newLabel;
}
private TextBlock CreateTextBlock(int row, int column, int columnSpan = 1)
{
TextBlock newTextBlock = new TextBlock();
newTextBlock.Foreground = Brushes.Silver;
Grid.SetRow(newTextBlock, row);
Grid.SetColumn(newTextBlock, column);
Grid.SetColumnSpan(newTextBlock, columnSpan);
grid.Children.Add(newTextBlock);
return newTextBlock;
}
private void InsertContent()
{
// Number
Label number = CreateLabel(0, 0, $"#{index + 1}");
number.HorizontalAlignment = HorizontalAlignment.Center;
number.VerticalAlignment = VerticalAlignment.Center;
number.FontSize = 17;
// Header
Label header = CreateLabel(0, 1, $"{submission.Name} ({submission.Rank})");
header.Foreground = Global.GET_BRUSH("HeaderForeground");
header.HorizontalAlignment = HorizontalAlignment.Left;
header.VerticalAlignment = VerticalAlignment.Center;
header.FontSize = 17;
// Timestamp
TextBlock timestamp = CreateTextBlock(0, 2);
timestamp.Inlines.Add(new Run("Timestamp"));
timestamp.Inlines.Add(new Run($"{submission.Timestamp}") { Foreground = Global.GET_BRUSH("HeaderForeground") });
timestamp.HorizontalAlignment = HorizontalAlignment.Right;
timestamp.VerticalAlignment = VerticalAlignment.Center;
timestamp.FontSize = 13.5;
// Range
TextBlock range = CreateTextBlock(1, 1);
range.Inlines.Add(new Run("Some text "));
range.Inlines.Add(new Run($"{submission.Range.ToStringWithDayNames()}") { Foreground = Global.GET_BRUSH("HeaderForeground") });
range.HorizontalAlignment = HorizontalAlignment.Left;
range.VerticalAlignment = VerticalAlignment.Center;
range.Margin = new Thickness(5, 0, 0, 0);
range.FontSize = 13.5;
// Conflict
Label conflict = CreateLabel(1, 2, "Nie wykryto konfliktu");
conflict.Foreground = Global.GET_BRUSH("GreenForeground");
conflict.HorizontalAlignment = HorizontalAlignment.Right;
conflict.VerticalAlignment = VerticalAlignment.Center;
conflict.FontSize = 13.5;
// Content
TextBlock content = CreateTextBlock(2, 1, 2);
content.Inlines.Add(new Run($"{submission.Content}"));
cotent.HorizontalAlignment = HorizontalAlignment.Left;
content.VerticalAlignment = VerticalAlignment.Top;
content.Margin = new Thickness(5, 0, 0, 0);
content.TextWrapping = TextWrapping.WrapWithOverflow;
content.FontSize = 13.5;
}
How it looks like
It perfectly works but when I added last TextBlock whole control is stretching to the right. In designer the same way of creating elements works, but in code no. What am I doing wrong?
I would like to achieve this effect with column 1 and 2 with the same width everywhere.
What I want
You have to set the dependency property Grid.IsSharedSizeScope to true in the StackPanel and then set the Property SharedSizeGroup for every ColumnDefinition to a string that definies the group with same size.
I dealt with this problem on my own. If someone will be having the same problem like me, I will write how to repair it.
In the place where my app initializes ScrollViewer I set property HorizontalScrollBarVisibility to Hidden. After setting this property to Disabled everything starts to work correctly.
There is something about this:
https://crmdev.wordpress.com/2010/01/16/how-to-deal-with-stubborn-silverlight-a-k-a-stubborn-me/

Xamarin.Forms loading large dataset with Android

I've been working on a Xamarin Forms project and I'm having trouble loading data into the Android application. It loads fine for iOS and UWP, but on Android it takes forever. This is happening on two different screens but I'm assuming the problem is the same. I'm sure there are better ways to load the data than what I am using.
This is the first screen I'm having trouble with on Android (screenshot from UWP):
It loads 15 products in each category into a horizontal scroller. The "See All" link loads all of the products in that category into a vertical scrolling grid. That's the second screen I'm having trouble with.
The code to load this view is:
var scroller = new TLScrollView
{
Orientation = ScrollOrientation.Horizontal,
ItemTemplate = new DataTemplate(() => ViewFactory.Merchandise.Invoke()),
HeightRequest = 320,
Padding = new Thickness(0, 0, 0, 10)
};
scroller.SetBinding(TLScrollView.ItemsSourceProperty, nameof(items));
scroller.ItemsSource = items.OrderByDescending(d => d.Cost).Take(15);
The ViewFactory code is:
public static Func<View> Merchandise { get; } = () =>
{
var mainGrid = new Grid() { WidthRequest = 250, Margin = 5 };
mainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
mainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(25, GridUnitType.Absolute) });
mainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(25, GridUnitType.Absolute) });
mainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(25, GridUnitType.Absolute) });
mainGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(35, GridUnitType.Absolute) });
var nameLabel = new Label() { Text = "Casket Name", LineBreakMode = LineBreakMode.TailTruncation, HorizontalTextAlignment = TextAlignment.Center };
var materialLabel = new Label() { Text = "MaterialName", HorizontalTextAlignment = TextAlignment.Center };
var costLabel = new Label() { Text = "Cost", HorizontalTextAlignment = TextAlignment.Center };
nameLabel.SetBinding(Label.TextProperty, "ItemName");
materialLabel.SetBinding(Label.TextProperty, "Material");
costLabel.SetBinding(Label.TextProperty, "CostFormatted");
GlobalModel globalModel = App.Current.MainPage.BindingContext as GlobalModel;
var catalogImage = new CachedImage
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
Aspect = Aspect.AspectFit,
LoadingPlaceholder = "MAFSLoader.gif",
CacheDuration = TimeSpan.FromDays(10),
RetryCount = 1,
RetryDelay = 100
};
catalogImage.BindingContextChanged += (s, o) => {
catalogImage.Source = null;
var item = catalogImage.BindingContext as CatalogItem;
if (item == null) return;
catalogImage.Source = item.SmallURL;
};
var buttonStyle = (Style)Application.Current.Resources["ButtonStyle"];
var addToCartButton = new Button { Text = "Add to Cart", BackgroundColor = Color.FromHex("#486E8E"), WidthRequest = 250, Style = buttonStyle };
addToCartButton.SetBinding(Button.CommandParameterProperty, "ItemID");
var imgTapGesture = new TapGestureRecognizer()
{
Command = new Command(() =>
{
if (addToCartButton.CommandParameter == null)
{
addToCartButton.SetBinding(Button.CommandParameterProperty, "ItemId");
}
var dictionary = new Dictionary<string, string>();
dictionary.Add(globalModel.CurrentFuneralHomeKey, addToCartButton.CommandParameter.ToString());
globalModel.ProductDetail.Execute(dictionary);
})
};
catalogImage.GestureRecognizers.Add(imgTapGesture);
addToCartButton.Clicked += new EventHandler(async delegate (Object o, EventArgs a)
{
var button = ((Button)o);
globalModel.AddToCart.Execute(button.BindingContext);
if (button.BindingContext.GetType() == typeof(Data.Corner))
{
await App.Current.MainPage.DisplayAlert("Shopping Cart", "You've added " + (button.BindingContext as Data.Corner).ItemName + " to your cart.", null, "OK");
}
});
mainGrid.Children.Add(catalogImage, 0, 0);
mainGrid.Children.Add(nameLabel, 0, 1);
mainGrid.Children.Add(materialLabel, 0, 2);
mainGrid.Children.Add(costLabel, 0, 3);
mainGrid.Children.Add(addToCartButton, 0, 4);
return mainGrid;
};
If anyone could point me in the right direction I'd be very grateful!
Interesting. I've just gone through the implementation of the TLSrollview. It looks like there is no recycling of elements and maybe lack some optimization (I can see that only if I debug). I see two options :
option 1 : Create a listview with recycling strategy on. For better performance, set also the row height. One item of your listview would be one row. The advantage of a listview is the performance gain from the recycling strategy (especially on Android). Note that on iOS and Android, it might be better to set it on or not.
option 2 : Create a custom layout. That might be a little overkill.

How do I send data back to the parent page in xamarin forms?

There is a label in the page Account which when tapped on will create a new ContentPage with a list of premise addresses. Tapping on any of the addresses should pop the ContentPage and send back a value to the Account page to set certain fields within the Account page. I tried to use Messaging center but it doesn't seem to be able to get the value. What am I missing?
This is the code that creates the ContentPage with the premise addresses:
private void ddlPremisesAddNavigation()
{
PremiseListPage = CreatePAContentPage();
var tgrddlPremiseAddress = new TapGestureRecognizer();
NavigationPage.SetHasNavigationBar(PremiseListPage, false);
tgrddlPremiseAddress.Tapped += (s, e) =>
{
Navigation.PushAsync(PremiseListPage);
};
// ddlPremiseAddresses.GestureRecognizers.Add(tgrddlPremiseAddress);
lblpremiseAddress.GestureRecognizers.Add(tgrddlPremiseAddress);
}
private ContentPage CreatePAContentPage()
{
#region Containers
ContentPage content = new ContentPage();
StackLayout pageContent = new StackLayout();
ScrollView addressesView = new ScrollView()
{
// BackgroundColor = Color.White,
Padding = new Thickness(20, 10, 20, 10)
};
StackLayout addressContainer = new StackLayout();
#endregion
#region Header
RowDefinitionCollection RowDefinitions = new RowDefinitionCollection();
ColumnDefinitionCollection ColumnDefinitions = new ColumnDefinitionCollection();
RowDefinitions.Add(new RowDefinition { Height = new GridLength(50, GridUnitType.Absolute) });
Grid header = new Grid()
{
RowDefinitions = RowDefinitions,
};
BoxView bg = new BoxView() { HeightRequest = 50, WidthRequest = 250, BackgroundColor = Color.White };
header.Children.Add(bg, 0, 0);
Grid.SetColumnSpan(bg, 5);
Label title = new Label()
{
Text = "Premise Address",
FontSize = 15,
FontAttributes = FontAttributes.Bold,
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand
};
header.Children.Add(title, 1, 0);
Grid.SetColumnSpan(title, 3);
Button back = new Button() { Image = "backArrow", BackgroundColor = Color.White };//
header.Children.Add(back, 0, 0);
Grid.SetColumnSpan(back, 1);
back.Clicked += back_Clicked;
#endregion
#region Address Frames
List<Frame> addrFrames = new List<Frame>();
if (premiseAddresses.Count <= 0)
{
foreach (PremisesModel premise in Premises)
{
premiseAddresses.Add(premise.PremiseId, premise.PremiseAddress);
}
}
foreach (KeyValuePair<int,string> item in premiseAddresses)
{
addrFrames.Add(CreatePAFrame(item));
}
#endregion
#region Add Content to Containers
foreach (Frame item in addrFrames)
{
addressContainer.Children.Add(item);
}
// < Button x: Name = "btnReqAmendment" Text = "Request amendment" Style = "{StaticResource buttonStyle}" Clicked = "btnReqAmendment_Clicked" />
Button addNew = new Button()
{
Text = "ADD NEW PREMISE ADDRESS",
Style = Application.Current.Resources["buttonStyle"] as Style,
HorizontalOptions = LayoutOptions.CenterAndExpand,
Margin = new Thickness(0, 20, 2, 15)
//FontSize = 12,
//WidthRequest = 220,
//HeightRequest = 40
};
addNew.Clicked += btnAddNewPremise_Clicked;
addressContainer.Children.Add(addNew);
addressesView.Content = addressContainer;
pageContent.Children.Add(header);
pageContent.Children.Add(addressesView);
content.Content = pageContent;
#endregion
return content;
}
private Frame CreatePAFrame(KeyValuePair<int, string> premiseAddress)
{
Frame frame = new Frame() { Padding = new Thickness(5, 5, 3, 5), HeightRequest = 60 };
StackLayout content = new StackLayout() { Padding = 0 };
content.Orientation = StackOrientation.Horizontal;
Label pAddress = new Label();
pAddress.Text = premiseAddress.Value;
pAddress.Style = Application.Current.Resources["LabelStart"] as Style;
pAddress.HeightRequest = 50;
pAddress.HorizontalOptions = LayoutOptions.StartAndExpand;
Image img = new Image()
{
Source = "rightArrow",
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.CenterAndExpand
};
content.Children.Add(pAddress);
content.Children.Add(img);
frame.Content = content;
var selectAddress = new TapGestureRecognizer();
selectAddress.Tapped += (s, e) =>
{
MessagingCenter.Send(this, "premiseId", premiseAddress.Key);
Navigation.PopAsync();
};
frame.GestureRecognizers.Add(selectAddress);
return frame;
}
And this is how it subscribes to Messaging center:
public Account()
{
MessagingCenter.Subscribe<ContentPage,int>(this, "premiseId", (sender,arg) =>
{
DisplayAlert("Premise Changed", "test", "OK");
selectedPremise = arg;
DisplaySelectedPremiseValues();
});
InitializeComponent();
}
One option could be using a global variable (e.g in App.cs) and setting this variable whenever a list item is tapped:
public static Address TappedAddress;
And before showing the listview reset that variable.

C# WPF MouseEnter and MouseLeave on Grid

I made 2 MouseEvents, they working, but the problem, that they working not like i have expected. I need these 2 events to be active when my mouse pointer is right in Grid Space, but now they working only if the pointer is on any Line.
my code:
// Grid 3 Rows.
Grid grid_Edit = new Grid();
Grid.SetRow(grid_Edit, 0);
Grid.SetColumn(grid_Edit, 1);
RowDefinition rowDef1 = new RowDefinition();
RowDefinition rowDef2 = new RowDefinition();
RowDefinition rowDef3 = new RowDefinition();
grid_Edit.RowDefinitions.Add(rowDef1);
grid_Edit.RowDefinitions.Add(rowDef2);
grid_Edit.RowDefinitions.Add(rowDef3);
grid_Edit.RowDefinitions[0].Height = new GridLength(1, GridUnitType.Star);
grid_Edit.RowDefinitions[1].Height = new GridLength(1, GridUnitType.Star);
grid_Edit.RowDefinitions[2].Height = new GridLength(1, GridUnitType.Star);
grid_Edit.MouseEnter += new MouseEventHandler(gridEdit_MouseEnter);
grid_Edit.MouseLeave += new MouseEventHandler(gridEdit_MouseLeave);
mainWindow_ref.Children.Add(grid_Edit);
// 3 lines
line1.Stroke = Brushes.White;
line1.X1 = 1;
line1.Stretch = Stretch.Fill;
Grid.SetRow(line1, 0);
line1.VerticalAlignment = VerticalAlignment.Center;
line2.Stroke = Brushes.White;
line2.X1 = 1;
line2.Stretch = Stretch.Fill;
Grid.SetRow(line2, 1);
line2.VerticalAlignment = VerticalAlignment.Center;
line3.Stroke = Brushes.White;
line3.X1 = 1;
line3.Stretch = Stretch.Fill;
Grid.SetRow(line3, 2);
line3.VerticalAlignment = VerticalAlignment.Center;
// add lines to grid_Edit
grid_Edit.Children.Add(line1);
grid_Edit.Children.Add(line2);
grid_Edit.Children.Add(line3);
private static void gridEdit_MouseLeave(object sender, MouseEventArgs e)
{
line1.Stroke = Brushes.White;
line2.Stroke = Brushes.White;
line3.Stroke = Brushes.White;
}
private static void gridEdit_MouseEnter(object sender, MouseEventArgs e)
{
line1.Stroke = Brushes.Black;
line2.Stroke = Brushes.Black;
line3.Stroke = Brushes.Black;
}
Set the background color of your Grid to Transparent, this will allow the Grid to capture the mouse events.

Unexpected NullReferenceException / InvocationTargetException

I have a pointing to null error but i dont see where the problem is since everything gets initalised before used. the points where the error acures i have given a blockquote. Like always im thankfull for every help.
Button topAddBut = null;
//Button botAddBut = null;
Button loadBut = null;
Button saveBut = null;
StackPanel topSP = null;
//StackPanel botSP = null;
public MainWindow()
{
InitializeComponent();
loadBut = new Button { Content = "Load", Width = 70, Height = 23 };
Canvas.SetRight(loadBut, 160);
Canvas.SetBottom(loadBut, 24);
canvas1.Children.Add(loadBut);
saveBut = new Button { Content = "Save", Width = 70, Height = 23 };
Canvas.SetRight(saveBut, 80);
Canvas.SetBottom(saveBut, 24);
canvas1.Children.Add(saveBut);
StackPanel topSP = new StackPanel { Width = 400, Height = 50 };
Canvas.SetLeft(topSP, 160);
Canvas.SetTop(topSP, 100);
AddWrapPanelTop();
AddTextBoxTop();
AddTopButton();
}
void AddTextBoxTop()
{
TextBox txtB1 = new TextBox();
txtB1.Text = "Text";
txtB1.Width = 75;
txtB1.Height = 75;
WrapPanel wp = (WrapPanel)topSP.Children[0];
wp.Children.Add(txtB1);
}
void AddWrapPanelTop()
{
WrapPanel myWrapPanel = new WrapPanel();
SolidColorBrush mySolidColorBrush = new SolidColorBrush();
mySolidColorBrush.Color = Color.FromArgb(255, 0, 0, 255);
myWrapPanel.Background = System.Windows.Media.Brushes.Magenta;
myWrapPanel.Orientation = Orientation.Horizontal;
myWrapPanel.Width = 4000;
myWrapPanel.HorizontalAlignment = HorizontalAlignment.Left;
myWrapPanel.VerticalAlignment = VerticalAlignment.Top;
topSP.Children.Add(myWrapPanel);
}
void AddTopButton()
{
TextBox txtB1 = new TextBox();
txtB1.Background = System.Windows.Media.Brushes.Magenta;
txtB1.Text = "Text";
txtB1.Width = 75;
txtB1.Height = 75;
topAddBut = new Button();
topAddBut.Click += new RoutedEventHandler(this.TopClick);
topAddBut.Content = "Add";
topAddBut.Width = 75;
// Add the buttons to the parent WrapPanel using the Children.Add method.
WrapPanel wp = (WrapPanel)topSP.Children[0];
wp.Children.Add(txtB1);
wp.Children.Add(loadBut);
this.topSP.Children.Add(wp);
}
void TopClick(Object sender, EventArgs e)
{
TextBox txtB1 = new TextBox();
txtB1.Background = System.Windows.Media.Brushes.Magenta;
txtB1.Text = "Text";
txtB1.Width = 75;
txtB1.Height = 75;
Button s = (Button)sender;
WrapPanel wp = (WrapPanel)s.Parent;
wp.Children.Remove(s);
wp.Children.Add(txtB1);
AddTopButton();
// Add the buttons to the parent WrapPanel using the Children.Add method.
}
}
}
You define the following:
StackPanel topSP = null;
Then you have
StackPanel topSP = new StackPanel { Width = 400, Height = 50 };
This is in your local scope though so will be destroyed when you exit the function
Finally you have
topSP.Children.Add(myWrapPanel);
This will still be set to null which is why your error occurs. Basically you are creating a local version of the same variable.
In order to resolve simply change the second definition to:
topSP = new StackPanel { Width = 400, Height = 50 };

Categories