Using a border to move a textbox - c#

I'm making a C# project with WPF and Visual Studio.
I'm stuck at trying to drag/move a TextBox around on my canvas in run-time.
I got the idea that, if you make a border thickness big enough, you could use the border for some sort of focus and then make an EventHandler for the border?
private Canvas DrawBox(ClassBox box)
{
Canvas myCV = new Canvas();
TextBox box1 = new TextBox();
box1.Background = new SolidColorBrush(Colors.Blue);
box1.BorderThickness = new System.Windows.Thickness(5);
box1.Foreground = new SolidColorBrush(Colors.White);
box1.MinWidth = 30;
box1.TextWrapping = TextWrapping.Wrap;
box1.AcceptsReturn = true;
myCV.Children.Add(box1);
Canvas.SetLeft(box1, box.Left);
Canvas.SetRight(box1, box.Right);
Canvas.SetTop(box1, box.Top);
return myCV;
}

Related

How can I detect Borderside of MouseEnter event in C#/WPF for resizing Grid Elements

Is it possible to set for each side of a border its own EventHandler for mouse-enter or mouse-leave event. For example for the Left-Border of a Grid and Top-Border of a Grid?
What I am actually trying to do is allow the user to resize Grid-Elements inside a Canvas that contain a TextBlock with the mouse.
I am inserting my Grid/Border into the Canvas with the following code:
Border border = new Border();
border.BorderThickness = new Thickness(2);
border.BorderBrush = Brushes.Black;
TextBlock tb = new TextBlock();
tb.HorizontalAlignment = HorizontalAlignment.Stretch;
tb.TextWrapping = TextWrapping.Wrap;
tb.Padding = new Thickness(5, 5, 5, 5);
tb.Text = fd.LabelText;
Grid grid = new Grid();
grid.Background = labelBackgroundBrush;
grid.Background.Opacity = myOpactiy;
border.DataContext = fd;
grid.Children.Add(tb);
border.Child = grid;
I found a good example at csharphelper.com . Although my implementation is still buggy this was a good inspiration for me. Maybe it can help others who want to do the same.

WPF textbox resizable text

I am trying to create resizable textboxes (so when the window is resized the textbox adjusts itself) programatically but the text inside the textbox is always very small in comparison to the textbox:
TextBox textBox = new TextBox();
textBox.Name = name;
textBox.Text = text;
textBox.SetValue(Grid.ColumnProperty, column);
textBox.SetValue(Grid.RowProperty, row);
textBox.SetValue(Grid.ColumnSpanProperty, columnspan);
textBox.SetValue(Grid.RowSpanProperty, rowspan);
So i added a binding to keep the text at the same size as the textbox:
Binding b = new Binding();
b.RelativeSource = new RelativeSource(RelativeSourceMode.Self);
b.Path = new PropertyPath(TextBox.ActualHeightProperty);
textBox.SetBinding(TextBox.FontSizeProperty, b);
but when i do this the text becomes way too big for the textbox.
What am i doing wrong/missing here?
You are binding the fontsize which is pixels to actual height which is in device independent units so its apples to oranges.
Is there any reason to not use a viewbox?
Something like (I'm doing this freehand so beware..no ide may have typos)
TextBox textBox = new TextBox();
Viewbox vb = new Viewbox();
vb.Child = textbox;
vb.Stretch = Uniform;
textBox.Name = name;
textBox.Text = text;
vb.SetValue(Grid.ColumnProperty, column);
vb.SetValue(Grid.RowProperty, row);
vb.SetValue(Grid.ColumnSpanProperty, columnspan);
vb.SetValue(Grid.RowSpanProperty, rowspan);

WPF drag and drop C# drag image as well

i dynamic populate a dock panel with answers from database and another dock panel with questions from the database as well. the answers will be populated as Labels and i trying to do a drag and drop with labels to textblock . Yes i can drag and drop , but the thing is i want to drag the label too . For example if the Label content is Hello , i want the hello to be dragged over with the word " hello " as well , for now , when i drag it , it doesn't drag the word as well , but when i drop it into a textbox , the word " hello " is dropped . I want to drag the animation or word as well together with the cursor .
this is my code :
private void PopulateQuestion(int activityID, int taskID)
{
IList<Model.question> lstQuestion = qn.GetRecords(taskID, activityID);
StackPanel sp = new StackPanel();
StackPanel stp = new StackPanel();
foreach (Model.question qhm in lstQuestion)
{
StackPanel sp1 = new StackPanel() { Orientation = Orientation.Horizontal }; // Question
TextBlock tb = new TextBlock();
tb.Text = qhm.QuestionContent;
tb.FontWeight = FontWeights.Bold;
tb.FontSize = 24;
sp1.Children.Add(tb);
StackPanel sp2 = new StackPanel() { Orientation = Orientation.Horizontal }; // Answer
Label tb1 = new Label();
tb1.Content = qhm.Answer;
tb1.FontWeight = FontWeights.Bold;
tb1.FontSize = 24;
tb1.MouseLeftButtonDown += tb1_Click;
sp2.Children.Add(tb1);
TextBox tbox = new TextBox();
tbox.Width = 100;
tbox.FontSize = 24;
tbox.AllowDrop = true;
tbox.FontWeight = FontWeights.Bold;
if (qhm.Answer.Trim().Length > 0 )
{
sp1.Children.Add(tbox);
}
sp.Children.Add(sp1);
stp.Children.Add(sp2);
}
dockQuestion.Children.Add(sp);
dockAnswer.Children.Add(stp);
}
private void tb1_Click(object sender, RoutedEventArgs e)
{
Label lbl = (Label)sender;
DataObject dataObj = new DataObject(lbl.Content);
DragDrop.DoDragDrop(lbl, dataObj, DragDropEffects.All);
lbl.IsEnabled = false;
lbl.Foreground = (SolidColorBrush)new BrushConverter().ConvertFromString("#FFFB3B46"); // Red
}
You can follow the strategy outlined in the link below, which essentially creates a new window and causes the window position to be updated with the mouse cursor.
http://blogs.msdn.com/b/jaimer/archive/2007/07/12/drag-drop-in-wpf-explained-end-to-end.aspx
So the main points from the page are that you decorate the cursor using the Adorner.
You can use the this.DragSource.GiveFeedback and other events on the DragSource event handlers to set up the Adorner.
Once you have the event handler, that gives you the opportunity to do something.
//Here we create our adorner..
_adorner = new DragAdorner(DragScope, (UIElement)this.dragElement, true, 0.5);
_layer = AdornerLayer.GetAdornerLayer(DragScope as Visual);
_layer.Add(_adorner);
So you can create your own Adorner by subclassing it. You can find more info on creating a custom adorner here:
http://msdn.microsoft.com/en-us/library/ms743737.aspx
take a look at this
http://blogs.msdn.com/b/adamroot/archive/2008/02/19/shell-style-drag-and-drop-in-net-wpf-and-winforms.aspx
the default wpf drag & drop's animation is ugly, if you want be show some text or image while dragging,you need
do something more.

Programmatically Add a Border to a StackPanel in Windows 8

I'm trying to set the following properties in the C# code behind of StackPanel that I need to add programmatically:
BorderThickness
BorderBrush
Any idea on how to set these programmatically?
I know this is a year later, but I have found an answer in case someone still needs it.
Here is a complete example
// Create a StackPanel and Add children
StackPanel myStackPanel = new StackPanel();
Border myBorder1 = new Border();
myBorder1.Background = Brushes.SkyBlue;
myBorder1.BorderBrush = Brushes.Black;
myBorder1.BorderThickness = new Thickness(1);
TextBlock txt1 = new TextBlock();
txt1.Foreground = Brushes.Black;
txt1.FontSize = 12;
txt1.Text = "Stacked Item #1";
myBorder1.Child = txt1;
Border myBorder2 = new Border();
myBorder2.Background = Brushes.CadetBlue;
myBorder2.Width = 400;
myBorder2.BorderBrush = Brushes.Black;
myBorder2.BorderThickness = new Thickness(1);
TextBlock txt2 = new TextBlock();
txt2.Foreground = Brushes.Black;
txt2.FontSize = 14;
txt2.Text = "Stacked Item #2";
myBorder2.Child = txt2;
// Add the Borders to the StackPanel Children Collection
myStackPanel.Children.Add(myBorder1);
myStackPanel.Children.Add(myBorder2);
mainWindow.Content = myStackPanel;
The StackPanel does not have a BorderThickness or BorderBrush properties. Only Background. If you want to set those, you would need to wrap the StackPanel in a Border control:
<Border x:Name="StackBorder">
<StackPanel>
</Border>
You can then call:
StackBorder.BorderThickness = new Thickness(1);
StackBorder.BorderBrush = new Windows.UI.Xaml.Media.SolidColorBrush(Windows.UI.Colors.Red);
You cannot set border properties on the StackPanel object itself. You place the StackPanel object inside a Border object and set the BorderThickness and BorderBrush properties on the Border object with something like:
myBorder.BorderBrush = Brushes.Black;
myBorder.BorderThickness = new Thickness(1);

Transparent canvas, with opaque elements

I'm trying to simulate an Android UI element that unfortunately doesn't exist in Windows 7 phone: ListPreference
I thought about using a Popup, that would take exactly the whole screen (to simulate a modal window).
So the popup would be made of the following elements:
Popup -> Canvas -> Border -> StackPanel -> RadioButtons
The Canvas would be fully transparent (or lightly whitish to clearly show that the element underneath aren't available)
The border would be made so it only big enough to contain all the RadioButtons
Then the StackPanel would be opaque and black.
Unfortunately, if I make the bottom canvas transparent, all children elements are also transparent. I can only make the elements more transparent.
The way transparency works is slightly different than with Android or iPhone (where it's quite easy to have a parent fully transparent, but opaque children).
Is there a way to make a parent fully transparent with the children opaque?
Or maybe someone could suggest another way to simulate a modal window.
Who knows, maybe someone even developed a ListPreference-like UIElement :)
Thank you
Here is how I ended up doing it.
It works in a similar fashion as ListPreference on Android. The constructor takes a string, an array of string and an int indicating which is the default value
When the windows is closed, the delegate Dismissed is called..
So you call it like so:
string[] choices = { "Choice 1", "Choice 2", "Choice3" };
ListPreference lp = new ListPreference("name", choices, 1);
lp.dismissed += new ListPreferences.DismissedHandler(lp_Dismissed);
the code:
public class ListPreference
{
Popup p;
string Name;
int oldValue;
public delegate void DismissedHandler(string name, bool changed, int newvalue);
public event DismissedHandler Dismissed;
public bool IsOpen
{
get
{
return p.IsOpen;
}
set
{
p.IsOpen = value;
}
}
public ListPreference(string name, Array elements, int default_value)
{
p = new Popup();
Name = name;
Dismissed = null;
oldValue = default_value;
double height = (App.Current.RootVisual as FrameworkElement).ActualHeight;
double width = (App.Current.RootVisual as FrameworkElement).ActualWidth;
p.VerticalOffset = SystemTray.IsVisible ? 32.0 : 0.0;
p.Height = height;
p.Width = width;
Canvas canvas = new Canvas();
SolidColorBrush colorBrush = new SolidColorBrush(Colors.Black);
colorBrush.Opacity = 0.75;
//Color.FromArgb(0xff, 0x8a, 0x8a, 0x8a));
canvas.Background = colorBrush;
//canvas.Opacity = 0.765;
canvas.Height = height;
canvas.Width = width;
p.Child = canvas;
Border border = new Border();
border.Width = width - 50.0 * 2.0;
border.BorderBrush = new SolidColorBrush(Colors.LightGray);
border.BorderThickness = new Thickness(5.0);
border.Background = new SolidColorBrush(Colors.Black);
canvas.Children.Add(border);
StackPanel panel2 = new StackPanel();
panel2.Orientation = System.Windows.Controls.Orientation.Vertical;
int i = 0;
foreach (string val in elements)
{
RadioButton radio1 = new RadioButton();
radio1.GroupName = "group1";
radio1.Content = val;
if (i == default_value)
radio1.IsChecked = true;
int j = i;
radio1.Click += (sender, args) => radio1_Checked(radio1, j);
i++;
panel2.Children.Add(radio1);
}
Button button1 = new Button();
button1.Background = new SolidColorBrush(Colors.Black);
button1.Foreground = new SolidColorBrush(Colors.White);
button1.Opacity = 1.0;
button1.Content = "Cancel";
button1.Margin = new Thickness(5.0);
button1.Click += new RoutedEventHandler(closeButton_Click);
panel2.Children.Add(button1);
border.Child = panel2;
// Open the popup.
p.IsOpen = true;
p.UpdateLayout();
border.Height = panel2.DesiredSize.Height + 5.0 * 2.0;
border.SetValue(Canvas.TopProperty, (height - border.Height) / 2.0);
border.SetValue(Canvas.LeftProperty, (width - border.Width) / 2.0);
p.UpdateLayout();
}
void closeButton_Click(object sender, RoutedEventArgs e)
{
// Close the popup.
p.IsOpen = false;
if (Dismissed != null)
{
Dismissed(Name, false, -1);
}
}
void radio1_Checked(object sender, int idx)
{
p.IsOpen = false;
if (Dismissed != null)
{
Dismissed(Name, idx != oldValue, idx);
}
}
}
I would suggest creating a Usercontrol that would do what you need. Set the LayoutRoot grid's background to PhoneSemitransparentBrush or changing the opacity will change the child element's opacity as well. Then your child elements can have any opacity you'd like. You can add this control as a child to the popup. Additionally, you can add doubleanimation to the popup with the opened and closed event triggers. Change the design height of the UserControl to 480x760 to simulate full page.
To answer your question. Using resources like PhoneSemitransparentBrush and TransparentBrush for the Canvas background is one of your options. Opacity will change the opacity of the whole UIElement including its children.

Categories