The call is ambiguous between the following methods or properties - WPF - c#

I have a WPF form that has some buttons to save user input, delete, and cancel. I was trying to add functionality such that whenever the user clicks the cancel button, there is a pop up a message. Instead it throws an exception in my controller:
"The call is ambiguous between the following methods or properties"
Here is my view:
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,0,0,0">
<Button Name="DeleteButton" Command="{Binding DeleteCommand}" CommandParameter="{Binding Path=SelectedStory}" Cursor="Hand" Height="25" IsEnabled="{Binding CanDelete}" Margin="5 0 0 0">Delete</Button>
<Button Name="SubmitButton" Command="{Binding SubmitCommand}" CommandParameter="{Binding Path=SelectedStory}" Cursor="Hand" Height="25" Margin="5 0 0 0">Submit</Button>
<Button Name="CancelButton" Command="{Binding CloseCommand}" CommandParameter="{Binding Path=SelectedStory}" Cursor="Hand" Height="25" Margin="5 0 0 0" >Cancel</Button>
</StackPanel>
My controller code:
public MetadataController(IGatewayService gateway, IEventAggregator eventAggregator, IDialogService dialog)
{
this.gateway = gateway;
this.eventAggregator = eventAggregator;
this.dialog = dialog;
// commands
this.CloseCommand = new DelegateCommand<StoryItem>(this.Close);//here i got the exception throwing "the call is ambiguous between the following methods or properties"
this.DeleteCommand = new DelegateCommand<StoryItem>(this.Delete);
this.SubmitCommand = new DelegateCommand<StoryItem>(this.Submit, this.HasFieldsRequiredBeforeSubmit);
this.eventAggregator.GetEvent<StorySelectedEvent>().Subscribe(OnStorySelected);
}
private void Close(StoryItem selsectedStory)//when i click my close button its not calling this method at all.
{
bool isConfirmed = this.dialog.ShowConfirmation("Are you sure you want to close?");
}
private void Delete(StoryItem selectedStory)
{
bool isConfirmed = this.dialog.ShowConfirmation("Are you sure you want to permanently delete ?");
if (isConfirmed)
{
this.gateway.DeleteStoryItem(selectedStory);
this.eventAggregator.GetEvent<CommandCompletedEvent>().Publish(CommandTypes.MetadataEntry);
}
}

The exception you're getting indicates that it doesn't how to access whatever method/property you're attempting to call. Perhaps there is some other method or property that is also called Close or CloseCommand and is causing the conflict?

The reason for the exception ,i do have the method already and i was trying to create one,that's why it throws that error.Thanks lot for the help guys.

Related

Pass update parameter in WPF using MVVM

I am having a problem updating Entity while using WPF MVVM and commands.
My WPF looks like:
<Popup Margin="10,10,0,13" Name="UpdatePopup" HorizontalAlignment="Left" VerticalAlignment="Top" Width="450" Height="100" IsOpen="{Binding IsOpen, Mode=TwoWay}">
<Border Padding="5" Background="WhiteSmoke">
<StackPanel Orientation="Horizontal" DataContext="{Binding CommendationEntity}" Width="450" Height="100">
<Label Content="Nazwa żódła" Margin="10,10,10,10" Width="75" Height="30"/>
<TextBox Text="{Binding Name}" Margin="10,10,10,10" Width="130" Height="30" x:Name="Name" />
<Button Command="{Binding DataContext.UpdateCommand, ElementName=UpdatePopup}" CommandParameter="{Binding id}" Content="Update" Margin="10,10,10,10" Width="80" Height="30"/>
<Button Command="{Binding DataContext.CancelCommand, ElementName=UpdatePopup}" Content="Anuluj" Margin="10,10,10,10" Width="80" Height="30"/>
</StackPanel>
</Border>
</Popup>
Now to update record I need id and new name so I am passing id with button binding, and I am having trouble passing name, my update method looks like:
public void UpdateEntity(object obj)
{
this.CommendationEntity = this._catalog.Commendations.Single(entity => entity.id == (int)obj);
this.CommendationEntity.Name = this.Name;
this._catalog.Commendations.Attach(this.CommendationEntity);
this._catalog.Entry(this.CommendationEntity).State = System.Data.Entity.EntityState.Modified;
this._catalog.SaveChanges();
}
And in the view model I have a property named:
public string Name
{
get { return _name; }
set
{
if (_name == value)
{
return;
}
this._name = value;
RaisePropertyChanged("Name");
}
}
But when I click Update id is passed as (object obj), with is right, but Name property does not update, what could be wrong?
Maybe its data context (DataContext="{Binding CommendationEntity}") as model name and view model property has same name? I'm new WPF so I can be wrong.
Or maybe there is a way to just click button and whole object will be passed as (object obj)?
this.Name indicates that the Name property belongs to the same class as the UpdateCommand property and then the path of the binding to the Name property should be set up the same way:
<TextBox Text="{Binding DataContext.Name, ElementName=UpdatePopup}" Margin="10,10,10,10" Width="130" Height="30" x:Name="Name" />
Otherwise you are binding to some other Name property or the binding simply fails.
Two possibilities:
Is the binding for Name correct? For the commands you are using DataContext.UpdateCommand, ElementName=UpdatePopup so it may be you need to do this as well. If the binding fails you don't get an exception but you should get a message in the output window of VS - worth checking there.
If for some reason in the Name setter: if (_name == value) (perhaps both are emptry strings?) is true then the name won't update.
As per you code you are trying to bind Name property of CommendationEntity with textbox control.It is not getting updated because you have not implemented NotifyPropertyChanged for this.CommendationEntity.Name property. You need to implement INotifyProperty at CommendationEntity to reflect the property changed of CommendationEntity class.

How would I go about passing a parameter on Loaded=" "?

I want to be able to pass an enum parameter upon Loaded=" " so I can easily identify the section that is loading without having to do string trickery on the name.
My Expander XAML:
<Expander Loaded="ExpanderLoaded" x:Name="Greeting_And_Opening_Expander" ExpandDirection="Down" IsExpanded="True" FontSize="14" FontWeight="Bold" Margin="5" BorderThickness="1" BorderBrush="#FF3E3D3D">
The Method I want it to call:
private void ExpanderLoaded(object sender, RoutedEventArgs e, Sections section)
{
//Do stuff
}
My Enum (It will be significantly larger, this is just a test run):
public enum Sections
{
Default = 0,
Opening = 1,
Verify = 2
}
How do I go about passing the enum as a parameter upon Loading?
I would do this using EventTrigger and InvokeCommand action, that way in your view model ElementLoaded (For lack of a better name) gets called and the appropriate Enumeration gets passed in.
<Expander>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding ElementLoaded}"
CommandParameter="{x:Static local:Sections.Default}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Expander>
In your ViewModel, you will have a property of type ICommand called ElementLoaded, then in your constructor you initialize it as so
ElementLoaded = new ActionCommand(ElementLoadedMethod);
and the ElementLoadedMethod can be as so
private void ElementLoadedMethod(object section)
{
var sectionEnumVal = (Sections)section;
}
This should be all you have to do.

Why are some of my buttons disabled at runtime?

When the window is opened, Abort is clickable, but all of the other buttons are not.
I put breakpoints at my getters:
public ICommand OkCommand
{
get { return _okCommand; }
}
and the button is disabled after it is called. I feel like I'm missing something obvious here. Is my binding not setup correctly? Or is it not being correctly initialized?
My ViewModel constructor:
[ImportingConstructor]
public MyViewModel(IMyViewModel view)
: base(view)
{
_okCommand = new DelegateCommand(OkHandler, IsValid);
_refreshCommand = new DelegateCommand(RefreshHandler, IsValid);
_testConnCommand = new DelegateCommand(TestConnectionHandler, IsValid);
}
My XAML for two of the buttons.
<StackPanel Orientation="Horizontal" Margin="0,14" HorizontalAlignment="Center" DockPanel.Dock="Bottom">
<Button Command="{Binding OkCommand}" Content="Ok" IsDefault="True" TabIndex="3" Margin="5,0"/>
<Button Content="Abort" IsCancel="True" TabIndex="4" Margin="0"/>
</StackPanel>
The second parameter of the DelegateCommand constructor is a Func that tells if the Command is executable. WPF uses this to determine if buttons, etc should be enabled.
I would check your IsValid Func / method whether it works okay, that is: returns true.

How to bind multiple eventhandlers on WindowsPhone 8 using XAML?

I'm about to make a control page that has several textblock.
each textblock will be "linked" to another page,
here's my xaml part
.........<phone:LongListSelector x:Name="settingSelector" ItemsSource="{Binding}">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel toolkit:TiltEffect.IsTiltEnabled="True" Tap="{Binding TapMethod, Mode=TwoWay}" >
<TextBlock Text="{Binding SetTitle}" FontSize="43" />
<TextBlock Text="{Binding SetDescription}" FontSize="19" Margin="0 0 0 10" />
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>..........
when I try this code behind :
.........public class SettingProperty
{
public string SetTitle{get; set;}
public string SetDescription{get; set;}
public string TapMethod{get; set;}
public SettingProperty(string setTitle, string setDescription, string tapMethod)
{
SetTitle = setTitle;
SetDescription = setDescription;
TapMethod = tapMethod;
}
}
List<SettingProperty> DataSetting()
{
List<SettingProperty> settingCollection = new List<SettingProperty>();
settingCollection.Add(new SettingProperty("Saldo", "cek saldo", "saldo_Tap"));
return settingCollection;
}
private void saldo_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
NavigationService.Navigate(new Uri("/saldo.xaml", UriKind.Relative));
}..........
I directly deployed them to my L520, I'm prety sure the culprit is the "Tap" binding on my stackpanel, when I omit it, the code works.
Did I miss something, or my whole method is just wrong?
our understanding of the "Tap" event is wrong.
You have two options here:
Either you clearly specify a METHOD NAME (not a string) as a event handler for the Tap event. For example:
Tap="MyControl_Tap"
In this case you must have a MyControl_Tap method in your control's code behind
OR, since you seem to be using the MVVM pattern, you have to create a ICommand, and then include your whole StackPanel in a Button, like this:
...<DataTemplate>
<Button Command="{Binding MyCommandProperty}">
<StackPanel toolkit:TiltEffect.IsTiltEnabled="True" >
<TextBlock Text="{Binding SetTitle}" FontSize="43" />
<TextBlock Text="{Binding SetDescription}" FontSize="19" Margin="0 0 0 10" />
</StackPanel>
</Button>
...

How to pass parameters to an ICommand?

I defined an ICommand-Class ReadPersons which reads all person objects from the database with a particular where-clause.
The command is being executed trough pressing a button and the where-clause is being insert in a textbox.
Question: How can i pass the text from the textbox to the Execute-Command?
MainWindow.xaml:
<Button Command="{Binding ReadPersons}">Read persons</Button>
<TextBox Name="textBoxWhereClause" />
ReadPersons.cs:
public void Execute(object parameter)
{
// Read all persons with my where-clause
string whereClause = ??? //todo
}
Yes you can.
<Button Command="{Binding ReadPersons}"
CommandParameter="{Binding Text, ElementName=textBoxWhereClause}">
Read persons</Button>
<Button Command="{Binding ReadPersons}" CommandParameter="{Binding SomeProperty}" Content="Read Persons"/>

Categories

Resources