How to clear the contents of a canvas in wpf? Tried canvas.clear() doesn't work.
Also how can i add zoom control in a wpf application? Zoom with a scroller to move the image.
Any help is greatly appreciated
You want to do MyCanvas.Children.Clear();
Tested with the following code:
<Grid>
<Canvas Name="MyCanvas"/>
<Button Click="Button_Click" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="200" Content="Clear"/>
</Grid>
and
public MainWindow()
{
InitializeComponent();
MyCanvas.Children.Add(new TextBlock() { Text = "Foo" });
}
private void Button_Click(object sender, RoutedEventArgs e)
{
MyCanvas.Children.Clear();
}
Related
I have a Button with a TextBlock embedded inside. When the Button is clicked, I want to be able to fetch the TextBlock inside it and modify it's members.
Here is how my button is setup:
<Button Click="Select_Click" Style="{StaticResource ButtonStyle}" HorizontalAlignment="Left" Padding="0,20,20,20">
<TextBlock Text="My text" FontSize="20" Style="{StaticResource TextBlockStyle}"/>
</Button>
In my code behind I want to be able to access the embedded TextBlock:
public void Select_Click(object sender, RoutedEventArgs e)
{
// Get the `TextBlock` from `sender` here
}
I've taken a look at the visual tree of the Button but I'm not seeing the TextBlock. I called GetVisualChildren() on the Button but I only see a Grid and no way to get to the Textblock.
The content of the Button is stored in its Content property and in your case, the TextBlock is the content of the Button.
public void Select_Click(object sender, RoutedEventArgs e)
{
Button button = (Button)sender;
TextBlock textBlock = (TextBlock)button.Content;
}
Just do some casting and it's pretty simple
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Establish_handlers();
}
void Establish_handlers()
{
Mybutton.Click += Mybutton_Click;
}
private void Mybutton_Click(object sender, RoutedEventArgs e)
{
Button clicked_button = (Button)sender;
TextBlock desired_text = (TextBlock)clicked_button.Content;
Textbox_Show_Button_Content.Text = desired_text.Text;
}
}
<StackPanel>
<Button x:Name="Mybutton">
<TextBlock>Hello</TextBlock>
</Button>
<TextBox x:Name="Textbox_Show_Button_Content"></TextBox>
</StackPanel>
Basically, I'm trying to make the canvas listen for a touch input (tap) and will increment the number of taps on screen. It isn't working when I touch the screen on my device. I debugged my code and nothing seems out of the ordinary except that the touch is not detected. I checked ZIndex and the canvas is in front of the screen to be touchable. How do I make it work?
XAML:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock Name="counter" FontSize="150" HorizontalAlignment="Center" TextWrapping="Wrap" Text="0" VerticalAlignment="Center" Margin="188,10,187,397"/>
<Button Content="Reset" HorizontalAlignment="Stretch" Margin="-18,535,-18,0" VerticalAlignment="Top" Click="Button_Click"/>
<Canvas ZIndex="0" Name="Canvas" HorizontalAlignment="Center" Height="535" VerticalAlignment="Top" Width="446" MouseLeftButtonDown="Canvas_MouseLeftButtonDown" MouseLeftButtonUp="Canvas_MouseLeftButtonUp" MouseLeave="Canvas_MouseLeave"/>
</Grid>
C#:
int taps = 0; // create var to detect number of times, user touches the screen
// Constructor
public MainPage()
{
InitializeComponent();
}
// method to register the touch as the finger is placed on the screen
private void Canvas_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
//Canvas c = sender as Canvas;
counter.Text = "TOUCHED!";
}
//method register the touch as the finger is lifting up from the screen
private void Canvas_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
//Canvas c = sender as Canvas;
taps++;
counter.Text = taps.ToString(); //convert var from int to string
}
//method register the touch as the finger leaves the area of the screen
private void Canvas_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
{
//Canvas c = sender as Canvas;
MessageBox.Show("You left the screen without lifting your finger. That does not count as a tap!", "Caution!", MessageBoxButton.OK);
}
// method to reset the counter to zero when button is pressed and released
private void Button_Click(object sender, RoutedEventArgs e)
{
taps = 0; // reset the count
counter.Text = taps.ToString(); // convert var from int to string
}
I don't know why you want to do it with Canvas - it won't work as you have nothing in this Canvas, so it can't register your click/tap, Canvas is also hard to adjust to screen. I think it can be done simpler way if you want to do it with MouseUp/Down - subscribe directly to Grid containing your elements instead of filling this Grid with additional Canvas:
In XAML:
<Grid x:Name="ContentPanel" Margin="12,0,12,0" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="7*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<TextBlock Name="counter" FontSize="150" HorizontalAlignment="Center" TextWrapping="Wrap" Text="0" VerticalAlignment="Center" Grid.Row="0"/>
<Button Content="Reset" HorizontalAlignment="Stretch" VerticalAlignment="Center" Click="Button_Click" Grid.Row="1"/>
<TextBlock Name="Touched" FontSize="50" HorizontalAlignment="Center" TextWrapping="Wrap" Text="Touched" VerticalAlignment="Center" Visibility="Collapsed" Grid.Row="2"/>
</Grid>
In code behind:
private int taps = 0;
public MainPage()
{
InitializeComponent();
ContentPanel.MouseLeftButtonDown += ContentPanel_MouseLeftButtonDown;
ContentPanel.MouseLeftButtonUp += ContentPanel_MouseLeftButtonUp;
}
private void ContentPanel_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
taps++;
counter.Text = taps.ToString(); //convert var from int to string
Touched.Visibility = Visibility.Collapsed;
}
private void ContentPanel_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
Touched.Visibility = Visibility.Visible;
}
// method to reset the counter to zero when button is pressed and released
private void Button_Click(object sender, RoutedEventArgs e)
{
taps = 0; // reset the count
counter.Text = taps.ToString(); // convert var from int to string
}
As you can see I've subscribed to Grid events (which covers whole screen) - but to make it work I had to set its Background Brush to Transparent, otherwise it will work only if you touch text.
There are many other ways to make your App work, but I hope this will help.
Is there a reason why you don't use the touch-events?
Instead of using MouseLeftButtonDown and MouseLeftButtonUp you should use TouchDown and TouchUp.
Only when you don't handle the touch events or the manipulation events they will be mapped to mouse events. In my experience with touch a single tap also not always gets mapped to MouseLeftButtonDown. As far as I know you could also with mouse events only recoginse one finger. When you want to count more fingers it's necessary to use the TouchDown/TouchUp events.
The problem lies in the overlapping style of the grid
so either make grid rows or define a stackpanel inside the grid, something like this.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<stackpanel>
<TextBlock Name="counter" FontSize="150" HorizontalAlignment="Center" TextWrapping="Wrap" Text="0" Margin="0,0,0,0"/>
<Canvas ZIndex="0" Name="Canvas" HorizontalAlignment="Center" Height="535" VerticalAlignment="Top" Width="446" MouseLeftButtonDown="Canvas_MouseLeftButtonDown" MouseLeftButtonUp="Canvas_MouseLeftButtonUp" MouseLeave="Canvas_MouseLeave"/>
<Button Content="Reset" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Top" Click="Button_Click"/>
</stackpanel>
</Grid>
Try and check now.
You should set your Background property. If you don't want any background set it to Transparent:
<Canvas ZIndex="99" Background="Transparent" Name="Canvas" HorizontalAlignment="Center" Height="535" VerticalAlignment="Top" Width="446" Tapped="Canvas_CountMyTaps"/>
(If you want the canvas to be on Top be sure to make it have a greater ZIndex than the other elements that it overlaps)
If not set (the default value is null) the element won't capture any taps/click etc, it will be as if they "fall through".
Also, consider using the Tapped event which is a "higher level" event that will respond to clicks, taps with the finger, stylus, etc.
I need to realize in C# .NET with WPF a ScrollBar Animation on a RichTextBox Control.
When i click on a button, the animation is supposed to bring me at the end of the text. For this I use the ScrollToEnd() method but i do not know how to perform the animation. I tried things with the BeginAnimation() method but nothing worked.
If anyone of you had any idea, it would be awesome. Thanks!
My XAML :
<Window x:Class="TestWpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="177.811" Width="338.88">
<Grid Margin="0,0,2,-1">
<RichTextBox x:Name="rtb" HorizontalAlignment="Left" Height="100" Margin="10,10,0,0" VerticalAlignment="Top" Width="319" ScrollViewer.VerticalScrollBarVisibility="Visible">
<FlowDocument>
<Paragraph>
<Run Text="RichTextBoxR
ichTextBoxRichTextBoxRichTextBoxRic
hTextBoxRichTextBoxRichTextBoxRichTextBoxRichTextBoxRichTextBoxRichTextBoxRichTextBoxRichTe
xtBoxRichTextBoxRichTextBoxRichTextBoxRichTextBoxRichTextBoxRichTextBoxRichTextBoxRichTextBoxRic
hTextBoxRichTextBoxRichTextBoxRichTextBoxRichTextBoxRichTextBoxRichTextBoxRichTextBoxRichTextBoxRichTextB
oxRichTextBoxRichTextBoxRichTextBoxRichTextBoxRichTextBoxRichTextBoxRichTextBoxRi
extBoxRichTextBoxRichTextBoxRichTextBoxRichTe
xtBoxRichTextBoxRichTextBoxRichTextBoxRichTextBoxRichTe
xtBoxRichTextBoxRich
TextBoxRichT
extBox"/>
</Paragraph>
</FlowDocument>
</RichTextBox>
<Button Content="Button" HorizontalAlignment="Left" Margin="122,121,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
</Grid>
My button click method in the XAML.cs :
private void Button_Click_1(object sender, RoutedEventArgs e) { rtb.ScrollToEnd(); }
Thanks a lot !
Best Regards.
Ok i found the solution. I created a new class from RichTextBox properties and added a Dependencyproperty to make it works :
class ExtRichTextBox : RichTextBox
{
public static DependencyProperty CurrentVerticalOffsetProperty =
DependencyProperty.Register("CurrentVerticalOffset", typeof(double), typeof(ExtRichTextBox), new PropertyMetadata(new PropertyChangedCallback(OnVerticalChanged)));
private static void OnVerticalChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ExtRichTextBox extRtb = d as ExtRichTextBox;
extRtb.ScrollToVerticalOffset((double)e.NewValue);
}
public double CurrentVerticalOffset
{
get { return (double)this.GetValue(CurrentVerticalOffsetProperty); }
set { this.SetValue(CurrentVerticalOffsetProperty, value); }
}
}
Sure you need to replace the old control by the new one then you use a storyboard to animate the scrollbar :
private void Button_Click_1(object sender, RoutedEventArgs e)
{
DoubleAnimation vertAnim = new DoubleAnimation();
vertAnim.From = rtb.VerticalOffset;
vertAnim.To = 100;
vertAnim.DecelerationRatio = .2;
vertAnim.Duration = new Duration(TimeSpan.FromMilliseconds(1000));
Storyboard sb = new Storyboard();
sb.Children.Add(vertAnim);
Storyboard.SetTarget(vertAnim, rtb);
Storyboard.SetTargetProperty(vertAnim, new PropertyPath(ExtRichTextBox.CurrentVerticalOffsetProperty));
sb.Begin();
}
Just replace coordonnates given to vertAnim.To property to scroll at the position you want.
I am trying to play an audio file (.wav) when a toggle button is pressed (and pause when pressed again). I had it working initially, but now I must of messed something up and am looking for help. This is how I'm doing it:
Create MediaElement in XAML
<MediaElement x:Name="myMediaElement" HorizontalAlignment="Center" VerticalAlignment="Center" PosterSource="vuvuzela.png" IsLooping="True" Source="Assets/vuvuzela.wav" Grid.Row="1" AutoPlay="False"/>
Then My ToggleButton is this:
<ToggleButton x:Name="ToggleButton" Content="Activate" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="2" FontSize="32" Style="{StaticResource ToggleButtonStyle1}" Checked="Tog_Checked" Unchecked="Tog_Unchecked"/>
And in my Code-behind, I have the ToggleButton's checked/unchecked handlers:
private void Tog_Checked(object sender, RoutedEventArgs e)
{
myMediaElement.Play();
}
private void Tog_Unchecked(object sender, RoutedEventArgs e)
{
myMediaElement.Pause();
}
Any ideas as to what might be going wrong or how to check it? Thanks!
EDIT: Debugged some more. Looks like the myMediaElement is not getting past the Opening state?
Apparently it was a hardware problem. My computer (MacBook running Bootcamp) was the issue. Finally found that answer in this post --> MediaElement in WinRT / Win8 does not work at all
Thanks for all the help though everyone
Is it important to you that your media element be visual like that?
Try this in your click event instead:
var _Media = new Windows.UI.Xaml.Controls.MediaElement() { AutoPlay = false };
var _Location = Windows.ApplicationModel.Package.Current.InstalledLocation;
var _Folder = await _Location.GetFolderAsync("Assets");
var _File = await _Folder.GetFileAsync("Ding.wav");
var _Stream = await _File.OpenAsync(Windows.Storage.FileAccessMode.Read);
_Media.SetSource(_Stream, _File.ContentType);
_Media.Play();
Have shown code required to play audio file. (code for playing next audio is bonus )
1.Add media element, play/pause/stop buttons to the XAML file.
<MediaElement x:Name="media" Source="Assets/page1/para1.mp3"
Grid.Column="0" Grid.Row="0" AutoPlay="True" />
<Button Click="StopMedia" Grid.Column="0" Grid.Row="1" Content="Stop" />
<Button Click="PauseMedia" Grid.Column="1" Grid.Row="1" Content="Pause" />
<Button Click="PlayMedia" Grid.Column="2" Grid.Row="1" Content="Play" />
2.Add the following code to the code-behind file:
private void StopMedia(object sender, RoutedEventArgs e)
{
media.Stop();
}
private void PauseMedia(object sender, RoutedEventArgs e)
{
media.Pause();
}
private void PlayMedia(object sender, RoutedEventArgs e)
{
media.Source = new Uri(this.BaseUri, "Assets/page1/para1.mp3");
media.Play();
}
protected override async void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
{
media.MediaEnded += media_MediaEnded;
}
private void media_MediaEnded(object sender, RoutedEventArgs e)
{
media.Source = new Uri(this.BaseUri, "Assets/page1/para2.mp3");
media.Play();
}
I'm trying to drag and drop an image from one spot on the canvas to another (should be relatively simple), but can't figure it out. The image which I want to move has the following XAML:
<Image Height="28" HorizontalAlignment="Left" Margin="842,332,0,0" Name="cityImage" Stretch="Fill" VerticalAlignment="Top" Width="42" Source="/Settlers;component/Images/city.png" MouseLeftButtonDown="cityImage_MouseLeftButtonDown" MouseMove="cityImage_MouseMove" MouseLeftButtonUp="cityImage_MouseLeftButtonUp"/>
The code is as follows:
bool isDragging = false; Point initMousePos; private void cityImage_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
isDragging = true;
initMousePos = e.GetPosition(theGrid); } private void cityImage_MouseMove(object sender, MouseEventArgs e) {
if (isDragging)
{
Image image = sender as Image;
Canvas.SetTop(image, initMousePos.X);
Canvas.SetLeft(image, initMousePos.Y);
image.Visibility = System.Windows.Visibility.Visible;
} }
private void cityImage_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) {
isDragging = false; }
What I do to accomplish what you want is to use
System.Windows.Controls.Primitives.Thumb
as the Root of a UserControl and set the ControlTemplate to display an image (within a border but it should work without as well), something like:
<Thumb Name="myRoot" DragDelta="MyRootDragDelta">
<Thumb.Template>
<ControlTemplate>
<Image ... >
... see below ...
</Image>
</ControlTemplate>
</Thumb.Template>
</Thumb>
Also, I bind the Source of the Image to a property of the class:
<Image.Source>
<Binding Path="ImageSource" RelativeSource=
{RelativeSource FindAncestor,
AncestorType=my:MyImageControl, AncestorLevel=1}" />
</Image.Source>
The UserControl has a named TranslateTransform (let's say translateTransform) whose properties X and Y are to be set in the DragDelta event handler:
private void MyRootDragDelta(object sender, DragDeltaEventArgs e)
{
translateTransform.X += e.HorizontalChange;
translateTransform.Y += e.VerticalChange;
}
Don't forget to add:
public ImageSource ImageSource { get; set; }
Hope this helps. If anything's unclear feel free to ask further.
You want to set the Left and Top properties of the Canvas to something other than the initial position. In the MouseMove handler you have to get the position relative to the parent. Also; make sure the parent element is a canvas and not a grid. You have a pretty big left and top margin on the image, aswell as a control with the variable name "theGrid".