|
hello,
I'm buzzy to create a custom listview witch has custom defined views based on the data it gets. I like
views with links such described in the example below and for example with a textbox and a textblock,
but it doesn't matter how it goes about it's idea.
I have a enum like this to know witch datatemplate must be used:
public enum tabType
{
tabbedTextBlock = 1,
tabbedLinkedBlock = 2
}
This class is a class to store data in
public class person
{
private string firstName;
private string lastName;
private int age;
private tabType type;
public person()
{
}
public person(string firstName, string lastName, int age, tabType type)
{
this.FirstName = firstName;
this.LastName = lastName;
this.Age = age;
this.tabType = type;
}
public string FirstName
{
get;
set;
}
public string LastName
{
get;
set;
}
public int Age
{
get;
set;
}
public tabType tabType
{
get;
set;
}
a list of objects too be bind to the list
public class sampledata : ObservableCollection<person>
{
public sampledata() :base()
{
Add(new person("foo", "fofoo", 23, tabType.tabbedLinkedBlock));
Add(new person("apple", "fruit", 21, tabType.tabbedTextBlock));
Add(new person("pineapple", "fruit", 17, tabType.tabbedLinkedBlock));
Add(new person("banan", "fruit", 47, tabType.tabbedLinkedBlock));
Add(new person("kiwi", "fruit", 34, tabType.tabbedTextBlock));
}
}
the tabtype is used to let the custom listview class know witch type of datatemplate most be used.
I have searched for a view day's but couldn't found a nice working solution, only an idea but
it's written in VB.net with windows forms. It can be found here.
thx,
DJohn
|
|
|
|
|
I define some new button style.
The style default background is image X.bmp and when on 'mouseOver' is true the image is changing to Y.bmp
I have 10 buttons on the code that need to use this style - and each of the button need to show different image as default different image on 'mouseOver' event.
I can set the bitmap on each button on the button constructor - but i don't know how to set the image in this case on the style definition level.
Someone can help here ?
|
|
|
|
|
|
Hi,
I have a combo box and keyboard shortcut to it. When I use keyboard shortcut to access this combo box, focus is moving combo box but its items are not moving up/down with the help of arrow keys..
Following is my xaml..
<Label Content="Security _Level:" VerticalAlignment="Center" Target="{Binding ElementName=securityLevelCombo}" />
<ComboBox Grid.Column="1" x:Name="securityLevelCombo" Margin="8,0,0,0" IsReadOnly="True" VerticalAlignment="Center" SelectionChanged="securityLevelCombo_SelectionChanged"/>
Please help..
Thanks
|
|
|
|
|
Am I missing something here?
I wrote the usual "viewmodel locator":
public class ViewModelBase
{
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.RegisterAttached("ViewModel",
typeof(System.Type), typeof(Window), new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnViewModelChanged)));
public static void OnViewModelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
d.SetValue(Window.DataContextProperty, Activator.CreateInstance((Type)e.NewValue));
}
public static void SetViewModel(DependencyObject d, Type value)
{
d.SetValue(ViewModelProperty, value);
}
public static Type GetViewModel(DependencyObject d)
{
return (Type)d.GetValue(ViewModelProperty);
}
}
Then I implemented a viewmodel like this:
public class Class1 : ViewModelBase
{
public String Test
{
get
{
System.Windows.MessageBox.Show("4");
return "Testing";
}
}
public List<String> Items
{
get
{
List<String> l = new List<String>();
l.Add("A");
l.Add("B");
return l;
}
}
}
then in my mainwindow.xaml, I just did:
local:ViewModelBase.ViewModel="{x:Type local:Class1}"
<TextBlock Background="Red" Text="{Binding Test}" Height="30" />
<ListBox Background="Green" ItemsSource="{Binding Items}" Height="100" />
works fine at runtime, but no data is shown at design time. I put a message box in OnViewModelChanged() and it does get called.
what do I need to do to see the bindings work at design time? I should point out I am using Visual Studio 2010.
|
|
|
|
|
Hmmm... I've found the whole d:DataContext="{d:DesignInstance Type=local:Class1}" thing... but it seems pretty flakey. If I paste it in, it might show the design time data once or twice, but when I rebuild, its gone again. Is there a way to set that automatically when I create the instance in OnViewModelChanged?
Not that it matters lol, since it doesn't work most of the time.
Any other ideas?
|
|
|
|
|
Say I have a dialog with a list box and 3 buttons: Add, Edit and Delete. The listbox displays a list of Widget objects.
I'm assuming the "proper MVVM way" is to do something like:
class ViewModel
{
public ObservableCollection<widget> Widgets { ... };
public Command AddCommand { ... };
public Command EditCommand { ... };
public Command DeleteCommand { ... };
}
Add then the ListBox.ItemsSource binds to Widgets, the Add button to AddCommand, Edit to EditCommand and so on...
Now is where I get confused on MVVM...
1) Typical Add button behavior is to auto select the new item. How would that happen? It was suggested to me that ViewModel expose a "CurrentItem" property for **2-way** data binding with the listbox. The AddCommand handler would update the CurrentItem after it creates it. Is this a good idea? To me, that seems hokey as it would force that behavior on everybody using the view model. Also, it would set that property in situations where it may not want to be set. Any ideas?
2) Obviously, Edit and Delete need to be disabled if no item is selected. I know how to do that the "non MVVM" way, but what is the MVVM way? I know the command has a CanExecute handler. Should all that logic happen in there? It would seem I would either need the list box or the selected item and the collection.
I guess I'm just trying to figure out where the line should be drawn at which code goes in the code behind and which goes in the view model.
I understand MVVM "purists" say ZERO code in the code behind, but it seems to me like you'll be creating a lot of properties, commands, etc and jumping through a lot of hoops to have all the bindable properties in the view model.
|
|
|
|
|
1) If there are certain situations you dont want the command to execute, the command should have a CanExecute property which can be set.
2) You achieve this through binding the enabled property of the command button to a property in your view model. This property should implement INotifyPropertyChanged . This property is then set to false triggering an INotify which will disable the button.
Hope this makes sesnse.
The funniest thing about this particular signature is that by the time you realise it doesn't say anything it's too late to stop reading it.
My latest tip/trick
Visit the Hindi forum here.
modified on Monday, October 18, 2010 3:01 AM
|
|
|
|
|
We have implemented an observable list, a selected item and an editable item. The editable item is used as a throw away object to support the user cancelling an edit.
I also find I refresh a list from the database after a CRUD operation on one of the items. Getting all the related data for a complex item is a pita. Say if you add a chair and want the room, apartment, floor, building information on the chair object (as with a view) then getting all those items is tedious. Although I may be doing this quite wrong!
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
SledgeHammer01 wrote: I understand MVVM "purists" say ZERO code in the code behind
Gah. That's just zealotry and stupidity rolled into one honking great pile of doggy poo. If the code doesn't touch on the model, there's no need to move it out of the view, e.g. you are updating a complex visual.
Typically, you'd have a SelectedItem in the VM and you'd simply have the CanExecute check to see if it's the default value or not.
SledgeHammer01 wrote: ypical Add button behavior is to auto select the new item. How would that happen? It was suggested to me that ViewModel expose a "CurrentItem" property for **2-way** data binding with the listbox. The AddCommand handler would update the CurrentItem after it creates it. Is this a good idea? To me, that seems hokey as it would force that behavior on everybody using the view model. Also, it would set that property in situations where it may not want to be set. Any ideas?
The VM should be there to support the view, so it exposes the behaviour that's appropriate for the view. I can't think of many instances where I've wanted to share one VM among different views so this may not be a real issue for you.
|
|
|
|
|
Hehe...
Ok, so if putting code in the code behind of a view is "allowed" in MVVM, what exactly is the point? I'll use my earlier example of a listbox and 3 buttons Add, Edit and Delete. Add is pretty much going to be a call to _model.Add(), delete is pretty much going to be a call to _model.Delete(), edit is pretty much going to be a call to _model.Update() or whatever. So, I would design my data access layer well and have add, edit and delete functionality THERE, not some chinsy view model. Now I don't mean put GUI stuff in the data access layer, but in my real world application, I have a data access layer that is something like:
public class Widget : INotifyPropertyChanged
{
}
public class Widgets :System.Collections.IEnumerable, INotifyCollectionChanged
{
}
So in this case, the view model would simply do something like:
public Widgets
{
get
{
return GetService<IDataStore>().Widgets;
}
}
that seems like adding a middle man class just for the hell of it doesn't it? I know I have seen some MVVM samples where the data access layer does NOT implement INotifyPropertyChanged and they do it in the VM... but to me that is hella retarded. I shouldn't need to re-implement INPC in every view model that consumes the data access layer objects.
So now the viewmodel seems to be a light weight redirection to the data store. Just to NOT have to put "listBox.ItemsSource = GetService<IDataStore>().Widgets;" in the code behind?
See, thats what I haven't wrapped my head around yet... trying to figure out what the hell the VM actually gives you in a real world application. I guess if you don't have a well designed data access layer it would make sense... but not having a well designed data access layer seems like a much bigger issue to me .
Thoughts? I'm seriously trying to figure this thing out.
|
|
|
|
|
Think about it from a slightly different perspective. Suppose that you have a page transition that doesn't have any reliance on a model, but is highly complex - where would you put the code for the trigger points in this? Would it make sense to put it in a ViewModel? Obviously not.
Now, suppose that your application has to interact with a model, this is where the VM comes into play. Stop thinking in terms of it being an unnecessary middleman - it's not, it's a vital layer in protecting and coordinating changes to your model. Most of the samples that you have seen tend to be fairly simplistic, with perhaps a single table being updated - this is not the way that it works in real life situations. Model interactions tend to be highly complex, with a single view potentially interacting with multiple model parts. The VM is vital for coordinating this. What people seem to get hung up on is that the VM simply seems to exist to provide details of INPC - this is not an accurate viewpoint (it's just that INPC plays an important part in updating the view). With a VM, you can isolate the logic of the view from the XAML that forms the view - which means that it becomes easier to test the application as you can test the VM without worrying about the view.
From a developers POV, the VM also allows you to decouple the design part of the application from the logic of the application, giving designers a chance to work with the code without having to have any knowledge about how to code themselves.
|
|
|
|
|
Hmmm... well, I guess in the cases where you need to "repackage" data from your DAL, it makes some sense. You could unit test your "repackaging" code.
Maybe one (or more) of my assumptions are incorrect?
A "Model" is a data object, correct?
My data provider assembly is a collection of "Models" and all the (non GUI) APIs to create, edit and delete them from the database.
All the objects in my data provider assembly implement IPNC. There is ZERO GUI code in there. The sole purpose of that assembly is to package the database data in a C# friendly way and hide everybody and everything from database calls. Nobody touches the database directly. It all goes through the data provider APIs. Any multi-threading, coordination, protection, etc. happens in here.
The viewmodel knows nothing about the view?
The view is coupled to the view model (through the DataContext and binding the properties)?
Right now, the majority of my views bind directly to DAL objects... I do have maybe 1 or 2 views where I had to "repackage" the data from the DAL so I could bind to it. Or maybe add a GUI state option, etc.
So for example, if I had a list of Widgets and I wanted to put that into a listbox, obviously it would be retarded to put the checkbox state in the DAL, so it would be repackaged in the view model. I guess I can understand that...
But in the cases where you are pretty much binding directly to DAL object?
I guess I've also read about people saying its kind of necessary to open your XAML in Expression Blend. Maybe it is... to be honest, I haven't tried opening my views in there in a long long time.
Sorry, maybe it sounds like I am trying to avoid MVVM. I'm not. I'm trying to understand its real thought process .
|
|
|
|
|
Sorry - I've just got round to reading your post. Right, in the case where you are just packaging data through to the model, there is no need to recreate the element in the VM. There are techniques you can use to parcel the call across though, and these exist in the VM - here's a post that explains one mechanism (link[^]).
Something you might want to consider though, is that the VM is also the point at which you need to sanitise your data before it gets committed to the database. Suppose that you want the user to enter a value between 1 and 10 - but you have to use a textbox for it; the VM should handle the validation to ensure that the data is reasonable. It has to protect the DAL.
|
|
|
|
|
1) It took me a while (and I still forget) that the view model is only used to present the state of the model to the view. You shouldn't have to worry about "everyone using the view model" because if it was for a different view, then you could create another view model without that CurrentItem property. For my first MVVM app I put way too much model related logic into the view model, and it really muddies the water.
2) Have you seen the RelayCommand? Even if you're not using MVVM-Light (which is a nice framework) it should point you in the right direction.
I've found learning MVVM is a lot like learning IoC/DI, you kind of have to re-learn the way you think about approaching and composing an application.
Have you figured out dialog messages? That took me a while to grok
|
|
|
|
|
I too often wondered about things like this. But I have finally come to terms that I think makes the most sense.
1) Go ahead and use the CurrentItem and force that behavior on the ViewModel. I think the hard fact is that ViewModels shouldn't be used across different presentation frameworks (e.g. WebForms, Asp.Net MVC, Windows Forms, WPF). This shouldn't happen for a multitude of reasons. The major point is your going to paint yourself into a very difficult and hard to use ViewModel to try and achieve compatibility with all of these frameworks. I have often fought with this too, and I came to some really good conclusions trying to learn the real way to treat ViewModels.
* ViewModels work best as an organizational structure. I treat ViewModels as an organization unit and not another technical layer of abstractions. This will give you optimal productivity and fewer bugs. With a well structured and organized ViewModel you create a more maintainable and agile product base. You shouldn't think about using ViewModels in "other" places than the one your creating it for, because it just doesn't work well.
* ViewModel code should be very simple. This means that the ViewModel code should be very simple that even a 2 year old can write them. Sure you can have a ViewModelBase class that contains some important infrastructure for your application, but after that your ViewModel code should be simple. With really simple viewmodel code, you can write up a ViewModel for exactly what you need in a few minutes.
Now, i know what some people are going to complain saying that they want to have a single ViewModel for everything. But with a focused and really simple to write ViewModels. It's painless to create more classes for your program to do exactly what you need.
Does this mean that your going to have a lot of ViewModels? YES.
Does this mean you have to write a ViewModel for Windows Forms and a different one for WPF? YES
If you think ViewModels should be another component of re-use, please take a look at this post from Udi about the fallacy of re-use.
http://www.udidahan.com/2009/06/07/the-fallacy-of-reuse/[^]
2) For the Commands, I like to use the RelayCommand implementation: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090030[^]
This is pretty much "The" way to handle code only ViewModels. This allows to have the behavior that your looking for.
<br />
public Person SelectedPerson { get; set; }
<br />
public ICommand EditCommand { get; private set; }<br />
<br />
private void OnEdit(object arg)<br />
{<br />
}<br />
<br />
public SomeViewModel()<br />
{<br />
EditCommand = new RelayCommand(OnEdit, x => SelectedPerson != null);<br />
}<br />
This works really well, and it's very simple too!
|
|
|
|
|
I'm using VS2010. You know how when you create a new silverlight project you get a form asking which web application to connect it to?
Let's say I copy the silverlight project to another directory and load it into another solution. How do I connect that silverlight project to the web application that exists in that solution?
The only way I've found so far is to create a new blank project and copy all the classes, assets, etc. over. There has to be a much better way.
Thanks
Just for clarification when I copy a silverlight project and then add it into an existing solution and build, the xap file is updated in the old web project's Client Bin folder. So it knows about it somewhere.
Brent
|
|
|
|
|
dbrenth wrote: There has to be a much better way.
I have noticed that trying to rename all files can be much more painful (and harder to work) then actually creating a new project and copying them over. But that is just my opinion.
Someone else may have found a better way.
The funniest thing about this particular signature is that by the time you realise it doesn't say anything it's too late to stop reading it.
My latest tip/trick
Visit the Hindi forum here.
|
|
|
|
|
I wrote a UserControl with a button inside: btn1
In the Main code, I dynamically instantiate some of my UserControl and dynamically wire an event handler to the click event of the UserControl Button btn1.
In this event Handler I want to find which object fired the event: oUserControl1, oUsercontrol2, oUserControlN ???
Thanks
Jean
public partial class MainWindow : Window
{
int i = 0;
public MainWindow()
{
InitializeComponent();
}
private void newUserControl_Click(object sender, RoutedEventArgs e)
{
MyUserControl oMyUserControl = new MyUserControl();
oMyUserControl.Name = "UC" + i;
i++;
oMyUserControl.btn1.Click += new RoutedEventHandler(btn1_Click);
MyStackPanel.Children.Add(oMyUserControl);
}
void btn1_Click(object sender, RoutedEventArgs e)
{
}
}
|
|
|
|
|
Member 2475960 wrote: private void newUserControl_Click(object sender, RoutedEventArgs e)
Check if e.OriginalSource() gives you something (e.g. the name of the initiating control).
The funniest thing about this particular signature is that by the time you realise it doesn't say anything it's too late to stop reading it.
My latest tip/trick
Visit the Hindi forum here.
|
|
|
|
|
You perobably need to maintain your own list of controls that you created, and in your handler do something like this:
UserControl senderCtrl = sender as UserControl;
var dynamicCtrl = (from ctrl in this.myDynamicControls
where ctrl.Equals(senderCtrl)
select ctrl).FirstOrDefault();
if (dynamicCtrl != null)
{
}
.45 ACP - because shooting twice is just silly ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001
|
|
|
|
|
It's working. Not easy! Now, I've to find out why it's working I also have to find more documentation on dynamic UI in WPF
Thanks for your help
Jean
|
|
|
|
|
Hi,
I am using SilverLight DataGrid with RowDetail Template.
I am having toggleButton on click of that i want to show RowDetailTemplate which contain another child datagrid.
Problem is when i click on the second or third row of the parent grid the SelectionChanged event is not fired.But when i click on the first row toggle button it displays child datagrid.
Thanks,
Sumukh
sam
|
|
|
|
|
Hello,
I am not sure if this will help but I had a similar thing going on with a combo box in WPF. It was binded to a list of persons. The solution was to override the equals method of the person class.
|
|
|
|
|
I hope I am posting this in the correct forum - although it concerns ssrs, I think it is more a winforms / wpf question.
We have a wpf application using the winforms reportviewer. This report shows a pass / fail status and I am using wingdings font with chr(0252) to display a tick and chr(0251) to display a cross. This works really well in the report and for sending to a printer, but when exported to pdf both the characters turn info small dots - not really acceptable for our users.
I have seen multiple other posts about this issue as a known problem, there this is a post on Microsoft connect [^] that indicates it is fixed (on 5/6/2009).
I am wondering if I am missing something obvious on how to obtain a more recent version of ReportViewer that includes a fix?
Is anyone else aware of this issue or have a resolution? As this is used in quite a few different reports, I would much prefer to fix the issue, than change all the reports to use different characters or fonts.
Thanks,
Tim
|
|
|
|
|