|
First of all out the box WPF wraps the listbox control in what is called a CollectionViewSource. This can provide you with information on the currently selectedItem as well as sorting and grouping items.
Get the CurrentItem and on your ObservableCollection of buttons just call IndexOf() and pass in the item. This should give you your index.
for exampe:
In your view xaml on the listbox set
IsSynchronizedWithCurrentItem="True"
then in your viewmodel (just bare inmind my collection is of themes)
public MainViewModel()
{
_theme = new ObservableCollection<Themes>();
_themesView = CollectionViewSource.GetDefaultView(_theme);
_themesView.CurrentChanging += new CurrentChangingEventHandler(_themesView_CurrentChanging);
_themesView.CurrentChanged += new EventHandler(_themesView_CurrentChanged);
}
This allows you to than have access to the current item of the collection.
In the event below you can do whatever you want with the current object. eg; index of your button item that you have selected.
void _themesView_CurrentChanged(object sender, EventArgs e)
{
ListCollectionView view = sender as ListCollectionView;
int index = _theme.IndexOf(view.CurrentItem as Themes);
}
Hope this helps to some extent.
|
|
|
|
|
I have a user control whose data context is a ViewModel. The user control has a listbox bound to an ObservableCollection.
When I have to add a new object to the listbox, I click on the 'Add new' button that opens an Open-file-dialog. After selecting the file from this dialog, I want to do further operations in the ViewModel. What is the best way to call/refer a method of the ViewModel in the user-control code-behind? Please suggest a solution.
|
|
|
|
|
2, no 3, no, actually there are a number of ways to achieve this. Some, Galasofts MVVM Light use a static copy of the Viewmodel, there are also a controller type pattern and you can always pass an instance of the viewmodel around. And I'm confidant there are more solutions than that.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Could you please tell us which part of this scenario requires you to refer to the VM in the View? I can see nothing in there that indicates that you need to do this.
|
|
|
|
|
The code-behind of the user-control is handling the 'Add New' button click event because I wanted to work with the Open file dialog (and I thought I could not have openfiledialog in the ViewModel, but now it seems like I can do it with Relaycommand).
After selecting the file from the Open file dialog, I want the further operations to be done in the ViewModel, so here is where I need to refer to the VM from the view.
|
|
|
|
|
The standard way for doing this in an MVVM type application is to have an interface that copes with the OpenFileDialog, and use this.
What I mean by this, is that you have an interface (we'll call it IFileOpenDialog) and that you create a class that implements this interface. Now, this class would simply wrap the call to opening the file dialog, and you would register it with something like a service locator - then your VM retrieves an instance of this class from the service locator using the interface and uses that to open the dialog.
Typically, your command would look something like this:
private void OpenFile(object o)
{
IFileOpenDialog fileOpen = ServiceLocator.Get<IFileOpenDialog>();
fileOpen.Filters = "All files (*.*)|*.*|";
bool? result = fileOpen.ShowDialog();
if (result.HasValue && result.Value == true)
{
myFile = fileOpen.FileName;
}
} I've just knocked this up in the CP editor, so I apologise for any syntax errors, but hopefully this should demonstrate what I've been talking about.
|
|
|
|
|
Pete O'Hanlon wrote: I've just knocked this up in the CP editor
I think that answer requires a pregnant pause before continuing...
WE ARE DYSLEXIC OF BORG. Refutance is systile. Your a$$ will be laminated.
There are 10 kinds of people in the world: People who know binary and people who don't.
|
|
|
|
|
Well, what were you expecting?
|
|
|
|
|
Thank you very much Collin. This solution worked very well for me.
Can you please help me with one more problem? A listbox in the user control is not displaying any data. Here are the details :
The user control (ucPlane) datacontext is set to PlaneListViewModel. The PlaneListViewModel is having
a public property that provides an ObservableCollection of PlaneViewModel objects. This property is called PlaneList.
The listbox itemsource is set as follows :
<ListBox x:Name="lstPlane"
ItemsSource="{Binding Path=PlaneList}"
>
</ListBox>
A Datatemplate defined in the
<UserControl.Resources> section is defined as follows :
<DataTemplate DataType="{x:Type viewModel:PlaneViewModel}">
......
</DataTemplate>
Can you please provide an example or link to an appropriate example that does what I want to do? I searched on the net for a solution but they seem to be too complex for me. I just want to bind a listbox to an ObservableCollection by using 2 view models - PlaneListViewModel and PlaneViewModel.
|
|
|
|
|
Thank you Collin. After digging deep into it, I found the reason why the listbox was not getting populated. The View model had two constructors and that was the root problem. When we have more than one constructor for a class, the INotifyProperty changed does not work correctly. The PropertyChanged event is always equal to null, so it does not notify the listbox when the collection changes.
So when I changed the viewmodel to have only one constructor, it works perfectly.
Thanks once again for your help.
|
|
|
|
|
Hello,
I m in a bit trouble can any one please help me?
I have added a DataGrid on a usercontrol page in silverlight 4.And bind it to an 'xyz' table. When i m updating the contents of the table , m passing the xyzId of selected row which is in hidden column. Now were the problem arises m unable to get the value , it returns empty string . Any help appreciated?
Regards
|
|
|
|
|
You should NOT be working with the visual control when manipulating the data. You should be working with the underlying collection you have bound to the visual control.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Hello Holmes,
Thanks for your reply. I have bounded the datagrid Itemsource with service result.
That's the problem. Can you provide an sample or link to know how to get this done?.
Regards
|
|
|
|
|
Hello buddies,
Solved it this way:
clsXYZ _clsxyz= dgxyz.SelectedItem as clsXYZ;
Regards
|
|
|
|
|
Hi,
I want to add an image column to my data grid which is bound to a list. I had tried few options but didn't worked. No error coming but image is not getting loaded. what is the solution.
Thanks
|
|
|
|
|
Use DataGridTemplateColumn --> CellTemplate --> Image.
If no image is loaded and with no error then it must be a binding issue.
|
|
|
|
|
Hi,
I am new to silverlight. I have a web service method which returns a list. When i call it in the xaml page it is something like
webservice.myTestMethod() so where the return value goes. since we cannot assign the output directly to a variable how can we capture it
Thanks in advance
|
|
|
|
|
I assume this is a strongly typed list and you are trying to bind something from the xaml to it. If so, simply use an ObservableCollection to bind to, and fill it with the results of the web service call.
|
|
|
|
|
thanks for your reply can you pls explain with an eg. thanks
|
|
|
|
|
public ObservableCollection<MyClass> PropToBindTo { get; private set; }
private void FillData()
{
var data = new MyWebService().GetData();
foreach (var value in data)
PropToBindTo.Add(value);
} This is just an example, but if it isn't clear to you then you need to read up on the basics of Silvelight. I would suggest buying a decent book.
|
|
|
|
|
So playing with Silverlight 5 and I want to implement the doubleclick event on the datagrid, simple enough except the MouseLeftButtonDown does not fire.
If I use the MouseLeftButtonUp it fires but the e.ClickCount never seems to increment past the first click.
When testing against a TextBlock the event works perfectly - very irritating! Now I don't wish to template every cell in every DataGrid in the application so does anyone have any news on this issue.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Can someone please point me in the right direction? I'm already mostly bald, and I am pulling out what little hair that I have left!
Originally I had some XAML that looked something like this in my main window (I've left parts out for brevity):
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="TapeStream Management Console"
FontSize="20" TextAlignment="Center" VerticalAlignment="Center"/>
<TabControl Grid.Row="1">
<TabItem Header="Catalog">
<views:CatalogTab>
</TabItem>
<TabItem Header="Datasets">
... etc.
</TabItem>
... etc.
</Grid>
Under each tab item I had a UserControl that displayed the actual information. The DataContext for each UserControl was set in the code behind. Things rendered pretty much the way I expected. (Yeah, I know this UI is not going to win any awards, but it is a start.)
I had some issues with this implementation (trying to get a chance to prompt for the user to save changes when they switch to a different tab), and Collin Jasnoch[^] was kind enough to suggest an alternative approach. [^]
I got it to somewhat work after what he was telling me finally penetrated my thick skull (with a little extra pounding from Pete O'Hanlon[^]).
The problem that I have now is that it is rendering all screwy. The MainWindow XAML looks more like this now:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="TapeStream Management Console"
FontSize="20" TextAlignment="Center" VerticalAlignment="Center"/>
<TabControl Grid.Row="1" ItemsSource="{Binding ViewModels}" SelectedItem="{Binding SelectedItem}"/>
</Grid>
...
I now have a MainWindowViewModel class that is set as the DataContext for the MainWindow. It contains an ObservableCollection of my various ViewModels as per Collin's suggestion. I have a ResourceDictionary set up with the DataTemplates for my ViewModels / UserControls as suggested by Collin and Pete:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:views="clr-namespace:TapeStreamManagementConsole.View"
xmlns:vms="clr-namespace:TapeStreamManagementConsole.ViewModel">
<DataTemplate DataType="{x:Type vms:CatalogViewModel}">
<views:CatalogTab />
</DataTemplate>
<DataTemplate DataType="{x:Type vms:DataSetsViewModel}">
<views:DataSetsView />
</DataTemplate>
<DataTemplate DataType="{x:Type vms:TapeImageFilesViewModel}">
<views:TapeImageFilesView />
</DataTemplate>
</ResourceDictionary>
1) I cannot figure out any way to get tab headers and make the TabControl look "normal".
2) My UserControls have a ListBox on the left-hand side that no longer has scroll bars.
I tried changing my DataTemplates to look like this:
<DataTemplate DataType="{x:Type vms:CatalogViewModel}">
<TabItem Header="Catalog" >
<views:CatalogTab />
</TabItem>
</DataTemplate>
When I do that, I end up with Tabs with headings, but no content! Help!
WE ARE DYSLEXIC OF BORG. Refutance is systile. Your a$$ will be laminated.
There are 10 kinds of people in the world: People who know binary and people who don't.
|
|
|
|
|
|
Hi,
using MVVM I'm looking for a general guideline that tells me what type I should use for properties in the viewmodel that are exposing lists.
I think, in general it is a good idea to keep the type as basic as possible (e.g. not ObjectSet<T> but IQueryable<T> or IEnumerable<T> ) in order to hide implementation from the interface. Thus, I started using IEnumerable<T> . Unfortunately it turned out, that the WPF designer (VS 2010) doesn't like this very much. The editor popup of the Properties view doesn't show me the members of my record type T . It seems that the designer needs at least IQueryable<T> , ICollection<T> or T[] .
Does anyone know a reason for this? I found no issues in using IEnumerable<T> at runtime, only at design time.
Thanks,
Harry
|
|
|
|
|
Unfortunately, the Cider designer isn't the greatest designer in the world. One thing though - if your types are going to need to update the UI based off changes, you must make sure that they implement INotifyCollectionChanged .
|
|
|
|