CheckBox [Inside ListBox ItemTemplate] Checked Event is not triggering - c#

This is my xaml
<ListBox x:Name="HistoryList"
ItemsSource="{Binding HistoryCollection}"
>
<ListBox.ItemTemplate >
</DataTemplate>
<CheckBox x:Name="UpCheckBox" Height="50" Width="50" >
<interactivity:Interaction.Triggers>
<interactivity:EventTrigger EventName="Checked">
<interactivity:InvokeCommandAction Command="{Binding UpCheckedCommad}" CommandParameter="{Binding ElementName=UpCheckBox}"></interactivity:InvokeCommandAction>
</interactivity:EventTrigger>
</interactivity:Interaction.Triggers>
</CheckBox>
</DataTemplate>
</ListBox.ItemTemplate >
</ListBox >
In ViewModel I have used GalasoftMVVM Command Binding
public ICommand UpCheckedCommad
{
get { return new RelayCommand<Object>(x => { PerformUpforTracks(x); }); }
}
void PerformUpforTracks(object x)
{
//TODO
}
I used a CheckBox inside a ListBox ItemTemplate.But am not getting the Checked Event of CheckBox in the ViewModel .
I wanted to get the Checked Event from my ViewModel.Can anyone have any idea to resolve this issue?

Each instance of your ListBox.ItemTemplate is automatically given "the current item in the collection" as its DataContext. In your case, that is each individual item in the HistoryCollection. In your example, the EventTrigger is searching for the "ThumbsUpCheckedCommad" inside your current instance of the HistoryItem.
In order to force the EventTrigger to search in your desired ViewModel, you need to specify the "Source" property of your command binding. I suggest using the RelativeSource syntax, to search up the tree for the last Control to have your ViewModel as its DataContext.
It would look something like this.
{Binding Path=ThumbsUpCheckedCommand, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}

I got it By Binding Command by this way
Command="{Binding Path=DataContext.UpCheckedCommad,
ElementName=HistoryList}"

Related

How to access suggestion listbox of WPF toolkit autocompletebox in viewmodel

In my project i am using the autocompletebox of the WPF toolkit from dotnetprojects:
<input:AutoCompleteBox Grid.Row="0"
Height="30"
Width="300"
ItemsSource="{Binding Persons}"
SelectedItem="{Binding SelectedName, Mode=TwoWay}"
ValueMemberPath="DisplayName"
ItemTemplate="{StaticResource AutoCompleteBoxItemTemplate}"
ItemFilter="{Binding PersonFilter}"
Style="{DynamicResource AutoCompleteBoxStyle}"
x:Name="AutoCompleteBox">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<i:InvokeCommandAction Command="{Binding TextChanged}"
CommandParameter="{Binding ElementName=AutoCompleteBox}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</input:AutoCompleteBox>
In the event TextChanged i pass the AutoCompleteBox as parameter to the viewmodel:
private void TextChangedInternal(object obj)
{
var box = obj as AutoCompleteBox;
...
}
From this point on i have no idea how to access the suggestion listbox within the popup.
My intention is to highlight the entered query within the suggestions.
Has somebody an idea how to archive this?
You will need to change the item template to something you control. This means you set up an AutoCompleteBox.ItemTemplate. This item template will contain each result found.
This Tutorial is for silver light but is pretty much all you need to create your custom control to highlight the text in the results. Once you have that you add this in the data template of your ItemTemplate.

Binding to Selected in WPF combobox

I have a WPF, C# Application and acombobx like:
<ComboBox SelectedItem="{Binding MySelectedItem.MyString, ValidatesOnDataErrors=True}" ItemsSource="{Binding MyCollection}" />
Is there a way to bind to Selected, or let a command fire if a item is selected.
Background:
I want to start loading data based on the selected Item, the start triggger should be something like IsSelected or LostFocus
Any help or a different/better way of archive this would be very helpfully.
Thank you very much
There are couple of ways
1 - define your binded property as a full property and do the manipulations when the value changes:
private string myString;
public string MyString
{
get { return myString; }
set
{
myString = value;
// do your stuff here...
}
}
2 - Use interactivity and convert event to command:
<ComboBox ItemsSource="{Binding MyCollection}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding SelectedItemChangedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
Don't fordet to add the needed namespace:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
And implement the SelectedItemChangedCommand in your ViewModel

WPF Command: parameter from user control

I'm in my MainWindowView.xaml. It includes a usercontrol.
I'm trying to set a command with a parameter. This parameter is the selected row of a gridControl (devexpress item).
I have tried two binding, both wrong (they don't find the parameter):
<Button Command="{Binding DeleteCommand}" CommandParameter="{Binding Path=lst1, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type uc:ucImpianti}}}" Style="{DynamicResource BtnToolBar}"/>
and
<Button Command="{Binding DeleteCommand}" CommandParameter="{Binding ElementName=lst1, Path=FocusedRow}" Style="{DynamicResource BtnToolBar}"/>
How have I to write the binding to pass the selected row of a gridControl in a UC?
My command defition is:
public ICommand DeleteCommand { get; private set; }
private void DeleteRecord(object parameter)
{
Debug.WriteLine(parameter);
}
[...]
DeleteCommand = new DelegateCommand<object>(DeleteRecord, CanAlways);
It is customary in WPF to data bind a collection of a certain type to the ItemsSource property and a property of the type of object in the collection to the SelectedItem property (it makes no difference that this example uses a ListBox):
<ListBox ItemsSource="{Binding YourCollection}"
SelectedItem="{Binding YourSelectedItem}" ... />
With this set up, you can data bind directly to the YourSelectedItem property from the CommandParameter property:
<Button Command="{Binding DeleteCommand}" CommandParameter="{Binding YourSelectedItem}"
Style="{DynamicResource BtnToolBar}" />
a more general answer would be:
if you wanna access an object/property from a usercontrol, then the UserControl should expose the object/property with a Dependency Property and you can bind to this DP.
another way would be to check if the DataContext of the Usercontrol expose the property then bind to the Datacontext.Property of the usercontrol.
so for your case i would need some more information of your Viewmodel and View bindings

Binding Command to Viewmodel with ItemsSource from a StaticResource

I am trying to add an ItemsSource to a MenuItem while keeping the Command bound to my ViewModel (my Window's DataContext). So far, I haven't figured out a way to make it work. Before the ItemsSource is added, the binding is fine. The collection that I am trying to bind comes from a StaticResource. Can anybody help me out with this?
<MenuItem Command="{Binding OpenTeamPage}"
DisplayMemberPath="Name"
Header="Teams"
ItemsSource="{Binding Teams,
Source={StaticResource Container}}" />
I have tried using this and variations of it with no luck:
Command="{Binding OpenTeamPage,
RelativeSource={RelativeSource AncestorType=Window},
Mode=Default}"
If anybody could tell me how to use this ItemsSource while still binding my Command to my ViewModel, I would greatly appreciate it. I suppose I could put the Command in my Team model, but I would like to avoid that if possible.
EDIT : To clarify my problem, with the ItemsSource in place, the command in the ViewModel doesn't fire at all. Without the ItemsSource, the command fires. I would like to be able to have the ItemsSource and still be able to fire the command.
EDIT:
public class GameContainer
{
static GameContainer()
{
Teams = new ObservableCollection<Team>();
}
public static ObservableCollection<Team> Teams { get; set; } 
}
In App.xaml:
<data:GameContainer x:Key="Container" />
The collection is populated when the program is started.
My goal once I get this working is to pass the selected team to the Viewmodel, hopefully via CommandParameter, and display info regarding the selected team.
EDIT: I was mistaken in my original post. A bound collection coming from the Viewmodel does not work either.
This is the behaviour of MenuItem, Item having Child MenuItem won't fire Command and it also should not as it does not make sense. But if you still want to fire a command on Parent Item click,there are two options
You can use Interactivity Triggers on your MenuItem to call command on MouseDown event like
<MenuItem
DisplayMemberPath="Name"
Header="Teams"
ItemsSource="{Binding Teams,
Source={StaticResource Container}}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<cmd:EventToCommand Command="{Binding OpenTeamPage}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</MenuItem>
you can define a Attached Property for command and define the MenuItem MouseDown behaviour like
public static class MouseCommandBehavior
{
public static readonly DependencyProperty MouseDownCommandProperty =
DependencyProperty.RegisterAttached("MouseDownCommand",
typeof(ICommand),
typeof(MouseCommandBehavior),
new FrameworkPropertyMetadata(null, (obj, e) => OnMouseCommandChanged(obj, (ICommand)e.NewValue, false)));
public static ICommand GetMouseDownCommand(DependencyObject d)
{
return (ICommand)d.GetValue(MouseDownCommandProperty);
}
public static void SetMouseDownCommand(DependencyObject d, ICommand value)
{
d.SetValue(MouseDownCommandProperty, value);
}
private static void OnMouseCommandChanged(DependencyObject d, ICommand command)
{
if (command == null) return;
var element = (FrameworkElement)d;
element.PreviewMouseDown += (obj, e) => command.Execute(null);
}
}
}
and you can set this Property value on your menuItem
<MenuItem local:MouseCommandBehavior.MouseDownCommand="{Binding OpenTeamPage}"
DisplayMemberPath="Name"
Header="Teams"
ItemsSource="{Binding Teams,
Source={StaticResource Container}}">
MenuItem will not execute its command if it's not a leaf node. Only menu items that are leafs (items with no children) are executing a command.
This is probably done due to convention - when you click an items that has children you get the children shown immediately, otherwise there's a delay from mouse hover till children shown.
Although it's probably a bad idea (from UX point of view) to have command on a parent, it's possible:
<MenuItem DisplayMemberPath="Name"
Header="{Binding OpenTeamPage}"
ItemsSource="{Binding Teams, Source={StaticResource Container}}" >
<MenuItem.HeaderTemplate>
<DataTemplate>
<!--Probably need to make this button transparent-->
<Button Content="Teams"
Command="{Binding }"/>
</DataTemplate>
</MenuItem.HeaderTemplate>
<!--This style is for the children to fire the same command as the parent-->
<MenuItem.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Command"
Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type MenuItem}}, Path=Header}"/>
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
Depending upon your design, you'd might need to style the button to be transparent.

Access the same data a textbox in the XAML is bound to

WPF MVVM in ViewModel I want to access the same data a textbox in the XAML is bound to
The XAML on MainWindow.xaml has a textbox bound to StoredProcs/ProcName
<TextBox Name="txtProcName" Text="{Binding Path=StoredProcs/ProcName}"></TextBox>
And a Grid bound to StoredProcs
Whenever the grid selection changes, the bound text in the textbox changes as it should.
<DataGrid AutoGenerateColumns="False"
Height="300" Width="290"
HorizontalAlignment="Center"
Name="dataGrid1"
VerticalAlignment="Top"
ItemsSource="{Binding StoredProcs}"
IsSynchronizedWithCurrentItem="True"
Margin="-6,0" Grid.RowSpan="2" Grid.Row="0">
<DataGrid.Columns>
<DataGridTextColumn Header="Proc Name" Binding="{Binding ProcName}" >
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
I have a button that executes a procedure in MainWindowViewModel when clicked, that works
<Button Content="Create RDL" Command="{Binding CreateStoredProcedure}" />
In the CreateStoredProcedure code, I need to access the same data that is displayed in the textbox (not using code behind). I would think I need to get the StoredProcs/ProcName but can't figure out how to do that.
I tried adding CommandParameter to the XAML but don't know how to access it in the CreateStoredProcedure instructions as it won't allow me to add paramaters
void CreateStoredProcedureExecute()
{
string procName = "proc";
//procName = { StoredProcs/ProcName };
MessageBoxResult result =
MessageBox.Show(String.Format("Create Stored Procedure {0}", procName));
}
bool CanCreateStoredProcedure()
{
return true;
}
public ICommand CreateStoredProcedure
{
get
{
return new RelayCommand(CreateStoredProcedureExecute,
CanCreateStoredProcedure);
}
}
Unless I am misunderstanding your question, you should be able to get the value of the property that the TextBox is bound to from within CreateStoredProcedure.
One thing though, if you want the TextBox to update the property, make sure you add "Mode=TwoWay" to your binding expression:
<TextBox Name="txtProcName" Text="{Binding Path=StoredProcs/ProcName, Mode=TwoWay}"></TextBox>
Unless I misunderstood I think you want something like this?
<Button
Content="Create RDL"
Command="{Binding CreateStoredProcedure}"
CommandParameter="{Binding ElementName=txtProcName, Path=Text}"/>
However as the other answer states, you should be able to just access the property in the ViewModel that is backing the textbox from the command, but if for some reason you cannot my code should work as well.
(Assuming you are defining RelayCommand as defined by this MSDN article, this should fix your other problem)
public ICommand CreateStoredProcedure
{
get
{
return new RelayCommand<object>(
(object parameter) => CreateStoredProcedureExecute(parameter),
(object parameter) => CanCreateStoredProcedure);
}
}
private void CreateStoredProcedureExecute(object parameter)
{
string ProcName = parameter as string;
}
I will admit my somewhat inexperience with setting up commands like this, but I did find a working example in my code that followed this, so hopefully it helps.
I think KDiTraglia has the right solution. The only thing I would do differently is to bind the CommandParameter to the model, not the UI element.
<Button
Content="Create RDL"
Command="{Binding CreateStoredProcedure}"
CommandParameter="{Binding Path=StoredProcs/ProcName}" />
I'm assuming that StoredProcs/ProcName is a placeholder for a real, valid binding path.
Root around here for more information: http://msdn.microsoft.com/en-us/library/ms752308

Categories