I am developing an metro application (Windows 8) in c#, that allows; to drag the controls/elements (Button, text Boxes etc), and i am not sure how to do drag in metro app.
Please guide me,
Thanks in Advance
Here is complete source code. You can drag and drop any control onto canvas. Right now I am giving you example of button and textbox. For all other control the process is same.
XAML code
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="90"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<GridView
x:Name="GridViewControl"
AllowDrop="True"
Background="#FF2E5073"
CanDragItems="True"
DragItemsStarting="GridViewControl_DragItemsStarting"
SelectionMode="None"
>
<GridView.ItemTemplate>
<DataTemplate>
<Grid>
<TextBlock
FontSize="14"
Text="{Binding}"
/>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel
Orientation="Vertical"
/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
<Canvas x:Name="Form"
AllowDrop="True"
Background="Black"
Drop="Form_Drop"
Grid.Column="1"
/>
</Grid>
C# code
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var ObserControl = new ObservableCollection<string>() { "Textbox", "Button" };
GridViewControl.ItemsSource = ObserControl;
}
private void Form_Drop(object sender, DragEventArgs e)
{
object sourceItem;
e.Data.Properties.TryGetValue("Item", out sourceItem);
double XPos = e.GetPosition(GridViewControl).X - 160;
double YPos = e.GetPosition(GridViewControl).Y;
if (sourceItem.ToString() == "Textbox")
{
var newTextbox = new TextBox();
newTextbox.Text = "Textbox";
newTextbox.SetValue(Canvas.LeftProperty, XPos);
newTextbox.SetValue(Canvas.TopProperty, YPos);
Form.Children.Add(newTextbox);
}
if (sourceItem.ToString() == "Button")
{
var newButton = new Button();
newButton.Content = "Button";
newButton.SetValue(Canvas.LeftProperty, XPos);
newButton.SetValue(Canvas.TopProperty, YPos);
Form.Children.Add(newButton);
}
}
private void GridViewControl_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
{
var item = e.Items.FirstOrDefault();
e.Data.Properties.Add("Item", item);
}
}
Related
How to resize item in ListBox from C#? I can do ListBox.Height = 100; but I don't know how to resize items in ListBox. Help me, please.
I need to change the size of items in listBox and their number using the ManipulationDelta method.
Main xaml code:
<ListBox x:Name="tileList"
Grid.Row="0"
Margin="5"
ManipulationCompleted="tileList_ManipulationCompleted"
ManipulationDelta="tileList_ManipulationDelta">
<ListBox.RenderTransform>
<CompositeTransform/>
</ListBox.RenderTransform>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<toolkit:HubTile x:Name="hubMain"
Title="{Binding Title}"
Margin="3"
DisplayNotification="{Binding DisplayNotification}"
GroupTag="{Binding GroupTag}"
Message="{Binding Message}"
Notification="{Binding Notification}"
Size="Medium"
Source="{Binding ImageUri}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
and C# code:
private void tileList_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
{
if (e.PinchManipulation != null)
{
double newWidth = 0.0, newHieght = 0.0;
foreach (tileList lv in tileList.Items)
{
lv.Height = 10;
}
}
}
private void tileList_ManipulationCompleted(object sender, System.Windows.Input.ManipulationCompletedEventArgs e)
{
m_Zoom = 200 / 10;
}
Thanks.
You can always change the ItemTemplate of your ListBox inside the Xaml page
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Height="200" Width="200" /> //This is just an example you can use any control
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Hope this is what you wanted.
You need to access the Items of the Listbox and set the individual height for them like this,
foreach (ListBoxItem lv in YourListbox.Items)
{
lv.Height = 10;
}
I wrote code in XAML - WPF Browser Application - Page , just one Listview and one button to add new data to the listview (from other file), I am trying to make the first column auto size itself when the button is pushed, I am using Visual Studio c# 2010.
I've used the following method in the code behind, but AutoResizeColumns won't be recognized and gives an error.
Unfortunately, none of the previously suggested solutions worked with me.
The Code Behind
public partial class Page1 : Page, INotifyPropertyChanged
{
public Page1()
{
InitializeComponent();
this.DataContext = new Page1Model();
}
private void TestListe_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
public event PropertyChangedEventHandler PropertyChanged;
private void Button1_Click(object sender, RoutedEventArgs e)
{
TestListe1.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
}
}
XAML
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="3*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<ListView Name="TestListe1" Margin="68,22,421,8" FontSize="12" >
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Width="auto"> <GridViewColumn.HeaderTemplate>
<DataTemplate>
<TextBlock Text="ST1" Margin="10,0,10,1"/>
</DataTemplate>
</GridViewColumn.HeaderTemplate>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding One}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
<Button Name="Button1" Grid.Row="1" Height="27" Width="95" Margin="262,24,444,74" Click="Button1_Click" />
</Grid>
AutoResizeColumns is from the namespace System.Windows.Forms. I'm not sure if that will work with WPF or not. But you can set the width of the column to NAN to make it resize
In your XAML if you name your GridView as follows:
<GridView x:Name="dataGridView">
Then you could resize all columns with this
foreach (GridViewColumn c in dataGridView.Columns)
{
c.Width = 0; //set it to no width
c.Width = double.NaN; //resize it automatically
}
I want to be able to drag an item from a ListView, and drop it onto the a GridView that represents a list of UserControls.
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ListView
ItemsSource="{Binding}"
VerticalAlignment="Stretch" HorizontalAlignment="Left"
CanReorderItems="False" CanDragItems="True"
DragItemsStarting="DragItemsStarting">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Width="280">
<TextBlock Text="{Binding}" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Viewbox Grid.Column="1" Margin="0,20,0,0">
<GridView x:Name="BoardGrid"
Width="600" Height="600">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid MaximumRowsOrColumns="10"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
<DataTemplate x:Name="GameBoardCellWithPieceDataTemplate">
<Grid Background="Green" Width="50" Height="50">
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Viewbox>
</Grid>
In the code behind I create the GridItems, set the AllowDrop property an assign an eventhander to the Drop event.
public MainPage()
{
this.InitializeComponent();
Loaded += MainPage_Loaded;
this.DataContext = new List<string> { "Drag String 1", "Drag String 2" };
}
public void MainPage_Loaded(object sender, RoutedEventArgs e)
{
for (var row = 0; row < 5; row++)
{
for (var column = 0; column < 5; column++)
{
var myUserControl = new MyUserControl { AllowDrop = true };
myUserControl.Drop += PieceDropped;
BoardGrid.Items.Add(myUserControl);
}
}
}
private void DragItemsStarting(object sender, DragItemsStartingEventArgs e)
{
var dragItem = (string)e.Items.FirstOrDefault();
if (dragItem == null)
return;
e.Data.Properties.Add("dragItem", dragItem);
}
private void PieceDropped(object sender, DragEventArgs e)
{
object sourceItem;
e.Data.Properties.TryGetValue("dragItem", out sourceItem);
if (sourceItem == null)
return;
[...]
}
The drag behaviour works fine, but when I drop an item of the ListView onto the GridView(Item), the Drop event isnt fired.
When I set the AllowDrop on the GridView itself, the Drop event is fired. Or when I wrap the UserControl in a GridViewItem, and set the AllowDrop on the GridViewItem, also the Drop event is fired, but after that i'm having problems with the DataTemplateSelecdtor I use.
Any clue?
I have created a sample project (http://sdrv.ms/V2OpfE) to demonstrate the problem
I am trying to implement a dynamic ListBox that contains the "open files" of my program. Those files can be dragged from the ListBox into one of four Canvases.
That works all fine as long as the items are added in XAML before starting the program, however, once I add items to the ListBox via fileList.Items.Add("myitemname"); I get a NullReferenceException if I try to drop (dragging works) them into the Canvas at
DragDrop.DoDragDrop(listBox, dragData, DragDropEffects.Move);
Here the relevant part of my code:
public partial class MainWindow : Window
{
InitialDataObject _initData = new InitialDataObject();
public MainWindow()
{
InitializeComponent();
}
#region DragImage
private void DragImageStart(object sender, MouseButtonEventArgs e)
{
_initData._mousePoint = e.GetPosition(null);
}
private void DragImageMove(object sender, MouseEventArgs e)
{
Point mousePos = e.GetPosition(null);
Vector diff = _initData._mousePoint - mousePos;
if (e.LeftButton == MouseButtonState.Pressed && (
Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance) && ((sender as ListBox).SelectedItem != null))
{
var listBox = sender as ListBox;
var listBoxItem = listBox.SelectedItem;
DataObject dragData = new DataObject(_initData._dropIdentifier, listBoxItem);
DragDrop.DoDragDrop(listBox, dragData, DragDropEffects.Move);
}
}
private void CanvasDrop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(_initData._dropIdentifier))
{
var item = e.Data.GetData(_initData._dropIdentifier) as ListBoxItem;
(sender as Canvas).Background = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
DropImage(sender as Canvas, item);
fileList.UnselectAll();
}
}
private void CanvasDragEnter(object sender, DragEventArgs e)
{
if (!e.Data.GetDataPresent(_initData._dropIdentifier) || sender == e.Source)
{
(sender as Canvas).Background = new SolidColorBrush(Color.FromArgb(255, 240, 240, 240));
e.Effects = DragDropEffects.None;
}
}
private void DropImage(Canvas targetCanvas, ListBoxItem item)
{
//just to check if I got the right item in this method
MessageBox.Show(item.Content.ToString());
}
private void CanvasDragLeave(object sender, DragEventArgs e)
{
if (!e.Data.GetDataPresent(_initData._dropIdentifier) || sender == e.Source)
{
(sender as Canvas).Background = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
}
}
#endregion
private void sdfsdf(object sender, RoutedEventArgs e)
{
fileList.Items.Add("test");
}
}
class InitialDataObject
{
public Point _mousePoint = new Point();
public readonly string _dropIdentifier = "dropIdentifier";
}
XAML:
<Grid Height="Auto" HorizontalAlignment="Stretch" Margin="0,23,0,0" Name="gridSubmain" VerticalAlignment="Stretch" Width="Auto" Panel.ZIndex="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250" MaxWidth="250" MinWidth="250" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ListBox Height="Auto" Name="fileList" Width="Auto" Background="#FFE6E6E6" BorderBrush="{x:Null}" Panel.ZIndex="1" PreviewMouseLeftButtonDown="DragImageStart" PreviewMouseMove="DragImageMove" FontSize="16" ItemsSource="{Binding}" Margin="0" Grid.Row="2">
<ListBoxItem Content="dfgdfg" />
<ListBoxItem Content="sfsdf" />
<ListBoxItem Content="ghjgh" />
<ListBoxItem Content="cvbcvb" />
</ListBox>
<Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="112,196,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="sdfsdf" />
</Grid>
<Grid Grid.Column="1" Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="gridImage" VerticalAlignment="Stretch" Width="Auto">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Canvas Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="canvasImage1" VerticalAlignment="Stretch" Width="Auto" AllowDrop="True" Drop="CanvasDrop" DragEnter="CanvasDragEnter" Background="White" DragLeave="CanvasDragLeave" />
<Canvas Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="canvasImage2" VerticalAlignment="Stretch" Width="Auto" Drop="CanvasDrop" DragEnter="CanvasDragEnter" Grid.Column="1" AllowDrop="True" Background="White" DragLeave="CanvasDragLeave"/>
<Canvas Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="canvasImage3" VerticalAlignment="Stretch" Width="Auto" Drop="CanvasDrop" DragEnter="CanvasDragEnter" Grid.Row="1" AllowDrop="True" Background="White" DragLeave="CanvasDragLeave"/>
<Canvas Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="canvasImage4" VerticalAlignment="Stretch" Width="Auto" Drop="CanvasDrop" DragEnter="CanvasDragEnter" Grid.Column="1" Grid.Row="1" AllowDrop="True" Background="White" DragLeave="CanvasDragLeave"/>
</Grid>
Any ideas why it is working with existing items but not with ones added via fileList.Items.Add("..");? Also, with existing Items the fileList.UnselectAll(); works fine, but the extra added items stay selected and I can't get rid of the selection.
Problem in you CanvasDrop method. You expect ListBoxItem there, but get string, because SelectedItem property of list box have different values for items you create in xaml and items you add dynamically.
I had a problem with passing a parsed string to a button click event. It was solved in this thread here, but now there's another small problem but it's with LINQ TO XML. I'm making a page which will show all of the apps that I make and will be updated with XML which I'll host on my server. On that page I'm parsing the icon, the title, the price and the marketplace Uri of the apps. I'm binding the Uri and the title of the apps to a single hyperlinkbutton but the problem is that every hyperlinkbutton on the list takes me to the same marketplace page. How can I fix it so every hyperlinkbutton navigates to a different page?
Here's the code:
public partial class MorePage : PhoneApplicationPage
{
private string appLink;
public MorePage()
{
InitializeComponent();
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
WebClient client = new WebClient();
Uri uritoXML = new Uri("http://www.allanhaapalainen.com/AppsXML/MorePageXML.xml", UriKind.RelativeOrAbsolute);
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
client.DownloadStringAsync(uritoXML);
base.OnNavigatedTo(e);
}
public void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
XDocument moreApps = XDocument.Parse(e.Result);
morePageAppList.ItemsSource = from Apps in moreApps.Descendants("App")
select new MoreApps
{
MoreImage = Apps.Element("link").Value,
Price = Apps.Element("price").Value,
Title = Apps.Element("title").Value
};
var attribute = (from Apps in moreApps.Descendants("App")
select new MoreApps
{
AppAttribute = (string)Apps.Attribute("id").Value
}).FirstOrDefault();
string appAttr = attribute.AppAttribute;
var link = (from Apps in moreApps.Descendants("App")
where Apps.Attribute("id").Value == appAttr
select new MoreApps
{
AppUri = (string)Apps.Element("marketplace").Value
}).FirstOrDefault();
appLink = link.AppUri;
}
private void App_Name_Click(object sender, RoutedEventArgs e)
{
ShowMarket(appLink);
}
private void ShowMarket(string id)
{
MarketplaceDetailTask marketplaceDetailTask = new MarketplaceDetailTask();
marketplaceDetailTask.ContentIdentifier = id;
marketplaceDetailTask.Show();
}
}
AND THE XAML:
<ListBox Height="500" Width="Auto" Name="morePageAppList" Margin="0,0,0,0" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="173">
<Image Source="{Binding MoreImage}" Height="Auto" Width="Auto" />
<StackPanel Orientation="Vertical">
<HyperlinkButton Name="appName" Content="{Binding Title}" Margin="15,60,0,0" Click="App_Name_Click" />
<TextBlock Name="price" Text="{Binding Price}" Margin="28,0,0,0" Foreground="#FFBD0000" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Like I mentioned in your previous post, you can use the tag parameter. Update your DataTemplate
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="173">
<Image Source="{Binding MoreImage}" Height="Auto" Width="Auto" />
<StackPanel Orientation="Vertical">
<HyperlinkButton Name="appName" Content="{Binding Title}" Tag="{Binding}" Margin="15,60,0,0" Click="App_Name_Click" />
<TextBlock Name="price" Text="{Binding Price}" Margin="28,0,0,0" Foreground="#FFBD0000" />
</StackPanel>
</StackPanel>
</DataTemplate>
then in your event
private void App_Name_Click(object sender, RoutedEventArgs e)
{
var button = (HyperLinkButton)sender;
var selectedApp = (MoreApps)button.Tag;
ShowMarket(selectedApp.AppUri);
}