Sample Drag&Drop Behaviour Code is not working - c#

This is the behaviour copy pasted from wpf-tutorial page:
public class DragBehavior : Behavior<UIElement>
{
private Point elementStartPosition;
private Point mouseStartPosition;
private TranslateTransform transform = new TranslateTransform();
protected override void OnAttached()
{
Window parent = Application.Current.MainWindow;
AssociatedObject.RenderTransform = transform;
AssociatedObject.MouseLeftButtonDown += (sender, e) =>
{
elementStartPosition = AssociatedObject.TranslatePoint(new Point(), parent);
mouseStartPosition = e.GetPosition(parent);
AssociatedObject.CaptureMouse();
};
AssociatedObject.MouseLeftButtonUp += (sender, e) =>
{
AssociatedObject.ReleaseMouseCapture();
};
AssociatedObject.MouseMove += (sender, e) =>
{
Vector diff = e.GetPosition(parent) - mouseStartPosition;
if (AssociatedObject.IsMouseCaptured)
{
transform.X = diff.X;
transform.Y = diff.Y;
}
};
}
}
And this is my test page:
<Page x:Class="WPFApp.Pages.BehaviorPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WPFApp.Pages"
xmlns:b="clr-namespace:WPFApp.Behaviors"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Title="BehaviorPage">
<Grid>
<StackPanel >
<Border Background="LightBlue">
<d:Interaction.Behaviors>
<b:DragBehavior/>
</d:Interaction.Behaviors>
<TextBlock Text="Drag me around!" Width="110" FontSize="14"/>
</Border>
</StackPanel>
</Grid>
</Page>
When i want to debug 'OnAttached()' is never hit/called. So Drag&Drop also doesn't work.

Blend was included in VisualStudio2105 and comes with the interactivity dll. If you use the path: xmlns:d="http://schemas.microsoft.com/expression/2010/intera‌​ctivity" instead of xmlns:d="http://schemas.microsoft.com/expression/blend/2008" the OnAttached method gets called correctly.

Related

WPF Drag Control during runtime

I been working with winforms, so my knowledge of WFP is non existent, this is something i am trying to test.
In code I am generating few buttons and placing them on Canvas. Than after clik on any button, i am moving that button around, and after second click button should stay at the position where mouse cursor was when clicked.
If mouse cursor go outside canvas then button will stop follow it.
My problem is, that button is moving, but only when mouse cursor is over that button or any other control, but it is not moving while mouse cursor is traveling over Canvas.
XAML
<Window x:Class="WpfTestDrag.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfTestDrag"
mc:Ignorable="d"
Title="MainWindow" Height="522" Width="909">
<Grid>
<Grid.ColumnDefinitions >
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="130*"/>
<ColumnDefinition Width="33*"/>
<ColumnDefinition Width="120"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions >
<RowDefinition Height="40" />
<RowDefinition Height="*" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<Canvas Grid.Column="1" Grid.Row="1" x:Name="cnvTest" Width="auto" Height="auto" PreviewMouseMove="CnvTest_PreviewMouseMove"/>
<TextBlock x:Name="txbStatus" Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="2"/>
</Grid>
</Window>
C#
public partial class MainWindow : Window
{
Button bts;
Boolean isUsed = false;
public MainWindow()
{
InitializeComponent();
CreateButtons();
}
private void CreateButtons()
{
var xPos = 10.0;
var yPos = 15.0;
var Rnd = new Random();
for (int i = 0; i < 3; i++)
{
var btn = new Button();
btn.Name = "btn" + i;
btn.Content = "Button - " + i;
btn.Tag = "Tag" + i;
btn.Width = 150;
btn.Height = 150;
btn.Click += Btn_Click;
Canvas.SetLeft(btn, xPos);
Canvas.SetTop(btn, yPos);
cnvTest.Children.Add(btn);
xPos = xPos + btn.Width + Rnd.Next(-15,40);
yPos = yPos + btn.Height + Rnd.Next(-15, 40);
}
}
private void Btn_Click(object sender, RoutedEventArgs e)
{
bts = sender as Button;
if (isUsed == false)
{
isUsed = true;
}
else
{
isUsed = false;
}
}
private void CnvTest_PreviewMouseMove(object sender, MouseEventArgs e)
{
Point p = Mouse.GetPosition(cnvTest);
if (isUsed == true)
{
Canvas.SetLeft(bts, p.X);
Canvas.SetTop(bts, p.Y);
txbStatus.Text = bts.Name.ToString() + " isUsed:" + isUsed.ToString() + " -> xPos:" + p.X.ToString() + " yPos:" + p.Y.ToString();
}
}
}
Should I use something else than Canvas for this?
You should set the Background property of the Canvas to Transparent (or any other Brush) for it to respond to the mouse events:
<Canvas Grid.Column="1" Grid.Row="1" x:Name="cnvTest" Width="auto" Height="auto" PreviewMouseMove="CnvTest_PreviewMouseMove"
Background="Transparent"/>

Make a Playlist Dynamically

private Queue<Uri> playList = new Queue<Uri>();
playList.Enqueue(new Uri(#"D:\media1"));
playList.Enqueue(new Uri(#"D:\media2"));
playList.Enqueue(new Uri(#"D:\media3"));
Here I am making the playlist hard coded. But I want to populate the playList from a string array. How is it possible?
My string array is string[] mylist=new string[3];
mylist[0]=#"D:\media1;
mylist[1]=#"D:\media2;
mylist[2]=#"D:\media3;
I have done this:
for (int i = 0; i < mylist.Length; i++)
{
playList.Enqueue(new Uri(mylist[i]));
mediaelement.play();
}
But it is only playing the last media.....
The problem is that MediaElement doesn't actually have a playlist feature, but you can easily implement it yourself. Implement the MediaEndedEvent to your mediaElement and play the next element in your string array. My xaml code:
<Window x:Class="WpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="320*"/>
<RowDefinition Height="50*"/>
</Grid.RowDefinitions>
<MediaElement x:Name="mediaelement" Grid.RowSpan="1" LoadedBehavior="Manual" MediaEnded="mediaelement_MediaEnded"/>
<StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Center">
<Button x:Name="btnPlay" Content="Next" Click="mediaelement_MediaEnded" Width="50" Height="25" Margin="5"/>
</StackPanel>
</Grid>
</Window>
And the C# code:
public partial class MainWindow : Window
{
private string[] mylist = new string[3];
public MainWindow()
{
InitializeComponent();
mylist[0] = #"D:\media1";
mylist[1] = #"D:\media1";
mylist[2] = #"D:\media1";
mediaelement.Source = new Uri(mylist[0]);
mediaelement.Play();
}
private void mediaelement_MediaEnded(object sender, RoutedEventArgs e)
{
for (int i = 0; i < mylist.Length - 1; i++)
{
Uri current = new Uri(mylist[i]);
if (mediaelement.Source == current)
{
mediaelement.Source = new Uri(mylist[i + 1]);
break;
}
}
mediaelement.Play();
}
}

windows phone bing maps crashing

My app crashes in the emulator when u load the map and then move the map and zoom in instantly. ive tried many different soulutions i found on the internet as the only error i get is Catastrophic Failure and no further information (no line number or any error information whatsoever)
C# code
public sealed partial class MapView : MvxWindowsPage
{
double lat=0;
double lon=0;
Geolocator gl = new Geolocator();
MapIcon Micon = new MapIcon();
Geopoint blo;
public MapView()
{
this.InitializeComponent();
Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;
GetInitialPosition();
}
private MapViewModel ViewModel
{
get { return DataContext as MapViewModel; }
}
private bool HasViewModel { get { return ViewModel != null; } }
void HardwareButtons_BackPressed(object sender, Windows.Phone.UI.Input.BackPressedEventArgs e)
{
e.Handled = true;
Windows.Phone.UI.Input.HardwareButtons.BackPressed -= HardwareButtons_BackPressed;
ViewModel.NavigateFirst();
}
async void GetInitialPosition()
{
gl.DesiredAccuracyInMeters = 500;
gl.DesiredAccuracy = PositionAccuracy.Default;
IAsyncOperation<Geoposition> locationTask = null;
try
{
Geoposition gp = await gl.GetGeopositionAsync(
maximumAge: TimeSpan.FromMinutes(5),
timeout: TimeSpan.FromSeconds(10)
);
//LatitudeTextBlock.Text = geoposition.Coordinate.Latitude.ToString("0.00");
//LongitudeTextBlock.Text = geoposition.Coordinate.Longitude.ToString("0.00");
}
finally
{
DispatcherTimer dt = new DispatcherTimer();
dt.Interval = new TimeSpan(0, 0, 5);
dt.Tick += (sender, e) => ProgBar.Visibility = Visibility.Collapsed;
dt.Tick += (sender, e) => ProgBar.IsEnabled = false;
dt.Start();
}
}
}
}
Xaml:
<views:MvxWindowsPage
xmlns:Maps="using:Windows.UI.Xaml.Controls.Maps"
x:Class="Etgarim.Views.MapView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Etgarim.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:views="using:Cirrious.MvvmCross.WindowsCommon.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Maps:MapControl x:Name="OmNaMap" MapServiceToken="..."/>
<!--Visibility="Visible" Center="{Binding blo}"-->
<ProgressBar x:Name="ProgBar" Height="667"/>
</Grid>
Move the map control and the progress bar so they not over lapping, this should resolve the issue.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="667"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<ProgressBar Grid.Row="0" x:Name="ProgBar" />
<Maps:MapControl Grid.Row="1" x:Name="OmNaMap" MapServiceToken="..."/>
<!--Visibility="Visible" Center="{Binding blo}"-->
</Grid>

WPF usercontrol out of bounds of the Grid

I have a WPF app that I'm testing which loads a XML and visualizes it in a usercontrol. Now the issue I'm having is that every time I load my user control the HorizontalAlignment is okay, but the VerticalAlignment doesn't adept to the height size of the usercontrol.
Anyone has an idea how to solve this?
MainWindow.xaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:UserControls="clr-namespace:RackBuildingTesT.UserControls" x:Class="RackBuildingTesT.MainWindow"
Title="MainWindow" Height="578" Width="758" SizeChanged="Window_SizeChanged_1">
<Grid>
<DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Border DockPanel.Dock="Top" BorderBrush="Black" BorderThickness="1">
<Grid>
<Label Content="Welke rack laden" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<ComboBox x:Name="RackChooser" HorizontalAlignment="Left" Margin="100,0,0,0" VerticalAlignment="Top" Width="120" SelectionChanged="RackChooser_SelectionChanged"/>
</Grid>
</Border>
<Border DockPanel.Dock="Top" BorderBrush="Black" BorderThickness="1">
<Grid x:Name="RackGrid" Margin="0,0,0,0">
</Grid>
</Border>
</DockPanel>
</Grid>
MainWindow.xaml.cs
public MainWindow()
{
InitializeComponent();
LoadRackCombo();
}
private void LoadRackCombo()
{
var files = Directory.GetFiles(Properties.Settings.Default.FilePathXMLRack);
foreach (var item in files)
{
RackChooser.Items.Add(item);
}
}
private void RackChooser_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
this.RackGrid.Children.Clear();
this.Cursor = Cursors.Wait;
if (RackChooser.SelectedIndex == -1)
MessageBox.Show("Select a rack");
else
{
string rackFile = Convert.ToString(RackChooser.Items[RackChooser.SelectedIndex]);
UserControls.RackBuilder r = new UserControls.RackBuilder();
RackGrid.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
RackGrid.VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
r.Width = RackGrid.Width;
r.Height = RackGrid.Height;
var _r = TRack.CreateFromXMLFile(rackFile, null);
r.set_Rack(_r);
RackGrid.Children.Add(r);
}
this.Cursor = Cursors.Arrow;
}
private void Window_SizeChanged_1(object sender, SizeChangedEventArgs e)
{
RackGrid.Width = this.Width;
RackGrid.Height = this.Height;
}
RackBuilder.xaml.cs (xaml page is standard WPF usercontrol)
public RackBuilder()
{
InitializeComponent();
}
public TRack fRack { get; set; }
public void set_Rack(TRack value)
{
this.fRack = value;
this.InvalidateVisual();
}
protected override void OnRender(DrawingContext drawingContext)
{
if (this.fRack != null)
{
var xScale = this.Width / this.fRack.Size.Width;
var yScale = this.Height / this.fRack.Size.Height;
var smallest = 0.0;
if (xScale < yScale)
smallest = xScale;
else
smallest = yScale;
foreach (var hole in this.fRack.HolePositions)
{
drawingContext.DrawEllipse(Brushes.Aquamarine, null, new Point(hole.Position.X * xScale, hole.Position.Y * yScale),
hole.Diameter * smallest * 0.5, hole.Diameter * smallest * 0.5);
}
}
}
Result
Instead of adding your Control to a Grid, use the ContentControl and add it to its Content-Property.
It also stretches its child automatically.
I fixed it with putting the MainWindow SizeToContent to WidthAndHeight.

moving a textbox with mouse

I have a custom WPF control which consist of single TextBox
<UserControl HorizontalAlignment="Left" x:Class="WPFDiagramDesignerControl.Components.UcWBSBlock"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="100" Width="100" IsEnabled="True">
<Grid >
<TextBox x:Name="txtBox" IsEnabled="True" Background="AntiqueWhite" Margin="10,10,10,10" TextWrapping="Wrap"> </TextBox>
</Grid>
</UserControl>
The control is placed on Canvas called MyDesigner.
I want to move my control on canvas only if I click on textbox and move mouse. I don't want to move control when I click on margin between borders of control and textbox.
I started writting a code and it looks like that
public partial class UcWBSBlock : UserControl
{
bool textChanged = false;
bool isClicked = false;
Point startPoint;
DesignerItem parentItem;
DesignerCanvas parentCanvas;
public UcWBSBlock()
{
InitializeComponent();
txtBox.MouseDoubleClick+=new MouseButtonEventHandler(txtBox_MouseDoubleClick);
txtBox.MouseMove+=new MouseEventHandler(txtBox_MouseMove);
txtBox.PreviewMouseDown+=new MouseButtonEventHandler(txtBox_PreviewMouseDown);
txtBox.PreviewMouseUp+=new MouseButtonEventHandler(txtBox_PreviewMouseUp);
txtBox.Cursor = Cursors.SizeAll;
}
private void txtBox_MouseMove(object sender, RoutedEventArgs e)
{
if (isClicked)
{
Point mousePos = Mouse.GetPosition(parentCanvas);
parentItem = this.Parent as DesignerItem;
parentCanvas = parentItem.Parent as DesignerCanvas;
Point relativePosition = Mouse.GetPosition(parentCanvas);
DesignerCanvas.SetLeft(parentItem,DesignerCanvas.GetLeft(parentItem) - (startPoint.X - mousePos.X));
DesignerCanvas.SetTop(parentItem, DesignerCanvas.GetTop(parentItem) - (startPoint.Y - mousePos.Y));
}
}
private void txtBox_PreviewMouseDown(object sender, RoutedEventArgs e)
{
if (!isClicked)
{
isClicked = true;
parentItem = this.Parent as DesignerItem;
parentCanvas = parentItem.Parent as DesignerCanvas;
startPoint = Mouse.GetPosition(parentCanvas);
}
}
private void txtBox_PreviewMouseUp(object sender, RoutedEventArgs e)
{
isClicked = false;
}
}
}
However my control doesn't move :( What did I do wrong ?? It's hard to debug this :)
you are setting the left/top of the parent item, not your control:
DesignerCanvas.SetLeft(parentItem,DesignerCanvas.GetLeft(parentItem) - (startPoint.X - mousePos.X));
DesignerCanvas.SetTop(parentItem, DesignerCanvas.GetTop(parentItem) - (startPoint.Y - mousePos.Y));
should (probably) be like this:
DesignerCanvas.SetLeft(this,DesignerCanvas.GetLeft(this) - (startPoint.X - mousePos.X));
DesignerCanvas.SetTop(this, DesignerCanvas.GetTop(this) - (startPoint.Y - mousePos.Y));

Categories