I have done a lot of research but many of the suggestions are outdated (WinRT), I need to allow my apps users to resize a grid horizontally and not vertically but I simply cant find a event or anything that allows this!
Sure.
If you have this:
<Grid Width="200" Height="100" Background="Lime"
ManipulationDelta="Grid_ManipulationDelta" ManipulationMode="TranslateX" />
You can do this:
private void Grid_ManipulationDelta(object sender, Windows.UI.Xaml.Input.ManipulationDeltaRoutedEventArgs e)
{
var grid = sender as Grid;
grid.Width = grid.ActualWidth + e.Delta.Translation.X;
}
Looks like this:
Best of luck!
Related
Original problem: I want to call a function each time the soft keyboard is shown/hidden on my Xamarin.Forms ContentPage.
One option was to use a custom renderer where I have access to the keyboard observers. I haven't tried this yet; I thought I'd try banging my head with other approaches first.
Approach 1) Assign event handler to the Focused/Unfocused events of all entries on my page which trigger a keyboard show/hide, in the page's code-behind as follows:
EventHandler<FocusEventArgs> keyboard_handler = (object sender, FocusEventArgs e) =>
{
var binding_context = BindingContext as MyViewModel;
binding_context?.OnKeyboardShowing();
};
PasswordEntry.Focused += keyboard_handler; // doesn't trigger keyboard_handler
PasswordEntry.Unfocused += keyboard_handler; // doesn't trigger
UsernameEntry.Focused += keyboard_handler; // triggers
UsernameEntry.Unfocused += keyboard_handler; //doesn't trigger
Question 1: Why don't some of those trigger?
Approach 2) Use EventTriggers along with a custom TriggerAction<Entry> class, as follows:
Part of the XAML file showing one of the entries (which is in a grid, in a StackLayout in a ScrollView in a Grid, if you must know):
<Entry Grid.Row="0"
x:Name="UsernameEntry"
Margin="0,2"
HorizontalOptions="FillAndExpand"
Placeholder="User"
IsVisible="{Binding UsernameEnabled}"
Completed="Username_Completed"
IsEnabled="{Binding EnableControls}"
Text="{Binding Username, Mode=TwoWay}" >
<Entry.Triggers>
<EventTrigger Event="Focused">
<local:FocusedAction />
</EventTrigger>
</Entry.Triggers>
</Entry>
And the TriggerAction<Entry> class defined in the code-behind:
public class FocusedAction : TriggerAction<Entry>
{
protected override void Invoke(Entry entry)
{
Debug.WriteLine("Reached"); // Except it never reaches here.
}
}
Question 2: Why doesn't Invoke up there ever get triggered?
Am I missing something in my XAML, code-behind or somewhere else? I've checked the Xamarin docs, but as always, I've found them less than useless.
I have been trying to figure this out for ages and I am stumped.
I have the following XAML:
<TextBox x:Name="MyTextBox" Text="{Binding MyName, Mode=TwoWay}" Width="200">
<WinRtBehaviors:Interaction.Behaviors>
<Win8nl_Behavior:EventToCommandBehavior Event="TextChanged"
Command="TextChangedCommand"
CommandParameter="{Binding Text, ElementName=MyTextBox, Mode=OneWay}"/>
</WinRtBehaviors:Interaction.Behaviors>
</TextBox>
And in my View Model:
public ICommand TextChangedCommand
{
get
{
return new RelayCommand<string>((p) =>
{
var msg = new MessageDialog(string.Format("Hi there {0}", p));
msg.ShowAsync();
});
}
}
But the string value I am hoping to appear in the CommanParameter (p) is always null.
What am I doing wrong?
The best thing you can do is to pass in the text value as the CommandParameter.
Behaviors are not part of the Visual Tree, so they don't have access to the XAML scope and the capability to perform ElementName bindings. This blog post provides more details, and a suitable solution.
I have a DataTemplate which requires an event handler for one of the objects. This DataTemplate is contained in a ResourceDictionary. What is the best way to add an event handler to this template?
I tried defining the event handler in app.xaml.cs but the handler isn't executing. Creating a code behind file for the ResourceDictionary leads to load errors during app start up in MergedDictionaries.
from GraphStyles.xaml
<DataTemplate x:Key="PieTemplate">
<Grid HorizontalAlignment="Left" Width="350" Height="350" >
<Border>
<Charting:Chart
x:Name="PieChart"
Title="Play Attempts"
Margin="70,0" Loaded="PieChart_Loaded">
<Charting:Chart.Series>
<Charting:PieSeries
Title="Attempts"
ItemsSource="{Binding Items}"
IndependentValueBinding="{Binding Name}"
DependentValueBinding="{Binding Value}"
IsSelectionEnabled="True" />
</Charting:Chart.Series>
</Charting:Chart>
</Border>
</Grid>
</DataTemplate>
in App.Xaml.cs
private void PieChart_Loaded(object sender, RoutedEventArgs e)
{
var pieChart = sender as Chart;
var legendItems = ((PieSeries)pieChart.Series[0]).LegendItems;
foreach (LegendItem item in legendItems)
{
pieChart.LegendItems.Add(item);
pieChart.LegendStyle = item.Style;
}
}
Option 1
As far as I am aware you will have to reference the datatemplate in the page/usercontrol's Resources at the top. Use a merged dictionary so you can still utilize the graphstyles.xaml.
If you are uncomfortable as this breaks your convention, there is a rather long winded alternative:
Option 2
Use an MVVM Viewmodel and set the page/usercontrols DataContext.
Keep the datatemplate in the graphstyles.xaml and use an Attached Behavior to hook the Loaded event, passing the event trigger up to the viewmodels command.
Create an event in the ViewModel that the UI can respond to, then hook onto that and handle in the Views codebehind as you have done.
I must say I'm not mad on Option 2 as it kind of breaks some view/VM seperation but it should get the job done - note that you will have to pass the chart as an object through from the attached behavior, to the viewmodel then back to the view against before you cast it back to a Chart.
I tried making a small program where in I wrote code to drag a rectangle in svg. The program is quite simple. My problem is that the rectangle drags only diagnolly on the screen and not on the entire web page.
Here is my code..
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100%" height="100%"
onload="Init( evt )" >
<script type="text/ecmascript">
//<![CDATA[
var svgDocument;
var svgRoot;
var newP;
var bmousedown=0;
var myCirc;
function Init(evt){
svgRoot= document.getElementsByTagName("svg")[0];
newP = svgRoot.createSVGPoint();
myCirc = document.getElementById("mycirc");
}
function getMouse(evt){
var position = svgRoot.createSVGPoint();
position.x = evt.clientX;
position.y = evt.clientY;
return position;
}
function onMouseDown(evt){
bmousedown=1;
newP=getMouse(evt);
doUpdate();
}
function onMouseMove(evt){
if(bmousedown){
newP=getMouse(evt);
doUpdate();
}
}
function onMouseUp(evt){
bmousedown=0;
}
function doUpdate(){
myCirc.setAttributeNS(null, "x", newP.x );
myCirc.setAttributeNS(null, "y", newP.y );
}
// ]]></script>
<rect id="mycirc" fill: #bbeeff" x="0" y="0" width="80" height="80"
pointer-events="visible"
onmousedown="onMouseDown(evt)"
onmousemove="onMouseMove(evt)"
onmouseup="onMouseUp(evt)"/>
</svg>
Please help me as I am unable to understand why does it not move on the entire screen.
i see the problem recreated on firefox, but it's not a single problem, your code is all over the place. i suggest going back to the drawing board before posting specific questions.
i'd also recommend a good reference on SVG or using a JS vector graphics library, as it would simplify things a little and will ease up the development a lot, if you're not interested in getting down to the nitty-gritty.
Here is the correct solution: http://jsfiddle.net/mihaifm/5GHJs/
The mistakes I think you made:
onload="Init( evt )" makes the variable evt global, a bad and useless thing to have. All the functions are also global, but this should be ok for this example.
the function calls for onmousedown etc. were using this global evt. (wrong). In order to get the correct event for each call you need to register some handlers.
I have a button control to which I want add image as well as hyperlink property, i.e it should be an image button with link to other source. I tried
<Button Click="OnNavigationRequest" ToolTip="Orkut">
<Image Source="C:\Documents and Settings\SaurabhS\My Documents\Visual Studio 2008 \Projects\SaurabhSinhaDemos\WPF_Zone\AddressBook\AddressBook\images\orkut.jpeg"/>
<Hyperlink NavigateUri="http://www.orkut.com">Orkut</Hyperlink>
</Button>
and in code behind:
AddHandler(Hyperlink.RequestNavigateEvent,
new RoutedEventHandler(OnNavigationRequest));
public void OnNavigationRequest(object sender, RoutedEventArgs e)
{
var source = e.OriginalSource as Hyperlink;
if (source != null)
Process.Start(source.NavigateUri.ToString());
}
But got the following error:
content set more than once...
How should I do it?
In your code, the Button element contains two child elements. The Button element can only take one child element.
Wrap Image and Hyperlink in a StackPanel or some other layout container and the error will go away (see Int3's answer for an example).
Try following
<Button>
<StackPanel Orientation="Horizantal">
<Image Source="path to the image"/>
<Hyperlink NavigateUri="http://www.orkut.com"/>
</StackPanel>
</Button>