I have custom Picker with property
public EventHandler SelectedIndexChanged { get; set; }
and i want set this property from xaml.
like this GenderPicker.SelectedIndexChanged += GenderPicker_OnSelectedIndexChanged;
but from xaml
<elements:CustomPicker
SelectedIndexChanged="{What write there???}"/>
Just write the name of the method like Handle_SelectedIndexChanged and make sure that you create the method in your code-behind of the page where you are using the control, with the right signature, for instance:
private void Handle_SelectedIndexChanged(object sender, EventArgs args)
{
// ... your code here
}
You should be able to just press tab after you select an event handler and it will auto generate it in the code behind for you to add whatever logic you want. However, you if you are trying to use bindings it is slightly more complicated. You will need an ItemsSource.
ItemsSource="{Binding SelectedIndexChanged}"
In the view model you will also need-
public PickerFlyout Foo { get; set; }
And in the start you will need initialize what is in the picker.
Related
Subj, how can i get it?
<controls:Pivot.TitleTemplate>
<DataTemplate>
<mainPivot:MyUserControl Name="MainPivotHeader"/>
</DataTemplate>
</controls:Pivot.TitleTemplate>
Tried to find it via VisualTreeFinders, but it sees only pivot item.
UserControl shows a picture, but it depends on user. During first initialization, it is empty, because user is not yet logged in. So, i'd like to force its update.
I can use mvvm light messaging, but i'm looking for self-sufficient components. This forcing is rare, so i dont want to use messaging here.
You should bind the Title property of the Pivot to a property on a ViewModel. Your DataTemplate would then have it's DataContext already set to that object. When you need to refresh, you call some method on that object.
Example
public class ViewModel : INotifyPropertyChanged
{
private MyTitleObject _titleObject;
public MyTitleObject TitleObject
{
get { return _titleObject; }
set
{
_titleObject = value;
OnPropertyChanged("TitleObject");
}
}
public void Refresh()
{
TitleObject = new MyTitleObject();
// or refresh values directly on the object
}
...
}
You xaml for your Pivot would need to following
<controls:Pivot Title="{Binding TitleObject}">
</controls:Pivot>
When you want to refresh, call the refresh on the viewmodel.
I have a Windows Store application, following the MVVM pattern.
I have a Parent View (with matching Parent ViewModel) that contains a GridView control.
The ItemTemplate for that GridView control contains a Child View.
That child view contains a couple of buttons.
How do I wire it up such that when a user clicks a button on one of the ChildView controls, a method is called on the Parent ViewModel?
There are two methods for doing this.
first one that you can use is - bind your button to a command that is defined- in your parent viewmodel where you can do your work.
second one is - you can use mvvm messenger class. in which you have to send message from your button click eventhandler to your viewmodel. when you received this message add some eventhandler to it and perform your work there.
This is how I went about solving this problem.
Add an ICommand backed Dependency Property on the Child View code behind.
public static readonly DependencyProperty ChildButtonCommandProperty = DependencyProperty.Register("ChildButtonCommand", typeof(ICommand), typeof(ChildView),new PropertyMetadata(null, OnChildButtonCommandChanged));
public ICommand ChildButtonCommand
{
get { return (ICommand)GetValue(ChildButtonCommandProperty); }
set { SetValue(ChildButtonCommandProperty, value); }
}
private static void OnChildButtonCommandChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var self = (ChildView)sender;
self.ChildButtonCommand.Command = (ICommand)e.NewValue;
}
In the Parent ViewModel, add a public getter property of type ICommand, implemented with a RelayCommand that you can find here: https://relaycommandrt.codeplex.com/
In the Xaml of the Parent View, bind the ChildButtonCommand in the Child View:
<GridView.ItemTemplate>
<DataTemplate>
<views:ChildView ChildButtonCommand="{Binding ElementName=ParentView, Path=DataContext.PropertyOnParentViewModel}"/>
</DataTemplate>
Examine the binding syntax closely. Since we're in a DataTemplate for the GridView Item, our DataContext is not the Parent View Model.(It's the child item objects). If we want to bind the button command to the Parent View Model, we need a reference to something in our parent view. In this case, I named the view "ParentView". Using the Binding ElementName syntax, I could bind to the DataContext of the ParentView and more specifically a property on the ParentViewModel.
I'm working on a Windows 8 Store App (using the Grid App Template) and while I'm loading data from a server I want to show a ProgressRing and hide the GridView or ListView (depends on if the app is snapped or not) that will display the data once it is fully loaded.
The issue is that when the ViewModel is loading data I need to be able to change the VisualState.
I found what I thought was a solution Here, but this code will not build.
public class StateManager : DependencyObject
{
public static string GetVisualStateProperty(DependencyObject obj)
{
return (string)obj.GetValue(VisualStatePropertyProperty);
}
public static void SetVisualStateProperty(DependencyObject obj, string value)
{
obj.SetValue(VisualStatePropertyProperty, value);
}
public static readonly DependencyProperty VisualStatePropertyProperty =
DependencyProperty.RegisterAttached(
"VisualStateProperty",
typeof(string),
typeof(StateManager),
new PropertyMetadata((s, e) => //this throws the error
{
var propertyName = (string)e.NewValue;
var ctrl = s as Control;
if (ctrl == null)
throw new InvalidOperationException("This attached property only supports types derived from Control.");
System.Windows.VisualStateManager.GoToState(ctrl, (string)e.NewValue, true);
}));
}
ERROR: Cannot convert lambda expression to type 'object' because it is
not a delegate type
Does anyone know how to get the linked solution to work? Or is there a simpler method that I am completely missing (I'm a XAML newbie!)?
I'm not even sure if the listed solution will work because the "Snapped" vs "Full" states are managed by the base LayoutAwarePage class included with the template.
why not simply use a datatrigger bind to a viewmodel property like IsBusy {get;set;} to enable your Progressring?
How do you disable the selection single item from a GridView?
I have a GridView with it's ItemsSource bound to an IEnumerable<SampleDataItem>. I'd like to be able to programmatically not allow the selection of some items in the list while allowing selection of the others.
While I haven't done this, you should be able to use an ItemContainerStyleSelector on the GridView, the method gives you the container (GridViewItem) and the item you're binding to. From there you can set the IsEnabled property on the GridViewItem to false which makes it unselectable.
You'll also probably need to select a custom style as well since the default GridViewItem style will customise how a disabled item will look.
Update DataTemplateSelector Solution
public class IssueGridTemplateSelector : DataTemplateSelector
{
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
var selectorItem = container as SelectorItem;
if (item is Issue)
return IssueTemplate;
selectorItem.IsEnabled = false;
selectorItem.Style = RepositoryItemStyle;
return RepositoryTemplate;
}
public DataTemplate IssueTemplate
{
get;
set;
}
public DataTemplate RepositoryTemplate
{
get;
set;
}
public Style RepositoryItemStyle
{
get;
set;
}
}
Nigel's answer is great. I just added some attached properties to the WinRT XAML Toolkit that should make it simpler to do if you are populating your GridView using the ItemsSource property binding.
For me the usual way to modify the GridViewItem properties then was using GridView.ItemContainerStyle property. Using that method you would need to specify the IsEnabled property using a style and style setters don't support bindings in WinRT. Using the ItemContainerStyleSelector might be one way, but it requires defining a custom class.
I have created a GridViewItemExtensions class with an IsEnabled property that you can set on any control in your GridView.ItemTemplate like this:
xmlns:xyzc="using:Xyzzer.WinRT.Controls"
xyzc:GridViewItemExtensions.IsEnabled="{Binding IsEnabled}"
The property has a behavior of finding the GridViewItem in its ancestors visual tree and keeping its IsEnabled value synchronized to the GridViewItemExtensions.IsEnabled value set on its descendant.
Then as Nigel said - you still need to extract the template from a GridViewItem and modify it so the disabled items don't look out of place.
I have a class
public class Item
{
public string A { get; set; }
public Control B { get; set; }
}
I'm using MVVM with Silverlight. I have a custom view that is inherited from a standard view. Custom view has public property public ICollection MyItems { get; set; } which should store items described above.
In xaml of my view I have
xxxx.MyItems>
Item A="someText" B="_existingButton" />
Item A="someText2" B="_existingButton2" />
/xxxx.MyItems>
Initialize() method of View fails when trying to assign value for B.
How can I assign a reference to existing element for a custom collection item?
I don't exactly understand what you are trying to achieve, but to help you arrive at a solution, I recommend that you attempt your task in the code behind file first (i.e. in the .xaml.cs) file.
By doing this, you will be given much more informative help from the compiler and intellisense.
Once you've achieved what you wanted in the code behind, then try and implement it in the xaml file.