|
In silverlight, drawing a line, if zooming in it,the polyline will be deformation,a moving line will appear.
You can use bingmap for example.
MapPolyline line = new MapPolyline();
line.Stroke = new SolidColorBrush( Colors.Brown );
line.StrokeThickness = 3;
line.Locations = new LocationCollection();
double lon = 114.219340787406, lat = 23.0518068854053;
for ( int i = 0 ; i < 100 ; i++ )
{
int k = 1;
if ( i % 2 == 0 )
{
k = -1;
}
Location location = new Location( lat + k * 0.03, lon + 0.02 * i );
line.Locations.Add( location );
}
this.myMapLayer.Children.Add( line );
When you move the map amplifier to level 18th , moves to the line polyline, it will appear a line. And this line will move where map change.
How to solve this problem.
|
|
|
|
|
(Code below)
I create 200 RichTextBoxes into a collection on form load, so that I can populate a grid with them when the form is clicked.
When you click the form, it populates TestGrid with the 200 RichTextBoxes, one per row.
That part works fine, but whenever I change anything about the RichTextBoxes, like Background brush, or text, the memory just keeps on growing, each time I populate grid. I'm not ADDING text, it's the same text, every time. Nothing changes at all between grid refills.
Please, I implore you to copy this XAML and code to a new WPF project, and click on the form repeatedly, as you monitor task manager.
It's even worse if you change more properties other than text - like it can get to be 10 MB mem usage growth per refill.
I've looked on the web, to no avail. Makes no ******* sense.
WPF is great, but:
I've read from a lot of angry people on web about WPF memory probs. None of them talked about this scenario, though, unfortunately.
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ScrollViewer HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Name="ScrollViewer1">
<Grid Name="TestGrid">
</Grid>
</ScrollViewer>
</Grid>
</Window>
Imports System.Windows.Documents
Class MainWindow
Dim Riches As New Collection
Dim WorkRange As TextRange
Private Sub MainWindow_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
'HERE I'M FILLING THE RICHES COLLECTION WITH 200 RICHTEXTBOXES
Dim RichRange As Long, NewRich As RichTextBox
For RichRange = 1 To 200
NewRich = New RichTextBox
Riches.Add(NewRich)
Next
End Sub
Private Sub MainWindow_PreviewMouseDown(ByVal sender As Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles Me.PreviewMouseDown
Me.Title = "Start"
With TestGrid
.RowDefinitions.Clear()
.Children.Clear()
Dim RowRange As Long
For RowRange = 1 To 200
.RowDefinitions.Add(New RowDefinition)
Dim HeaderCell As RichTextBox
HeaderCell = Riches(RowRange)
With HeaderCell
WorkRange = New TextRange(.Document.ContentStart, .Document.ContentEnd)
WorkRange.Text = "Poo " & CStr(RowRange)
End With
.Children.Add(HeaderCell)
.SetRow(HeaderCell, RowRange - 1)
.SetColumn(HeaderCell, 0)
Next
End With
GC.Collect()
Me.Title = "Stop"
End Sub
End Class
If you're going to help me out and test this yourself, you can try commentizing the 2 lines of code that changes the text:
WorkRange = New TextRange(.Document.ContentStart, .Document.ContentEnd)
WorkRange.Text = "Poo " & CStr(RowRange)
By removing those two lines, no more memory growth will be visible in task manager.
Thanks a bunch!
|
|
|
|
|
Hello To All,
I am new to MVVM with Silverlight.
MyTestView --> View (Button, Grid)
MyTestViewModel --> ViewModel (WCF Service Methods)
In my button call I have assigned the DataContext. I have to fill grid with the data that have been returned from the service call in the same click event in the View's code behind.
Any help regarding this will be greatly appreciated..
Thanks in adv...
|
|
|
|
|
As in your other post, you are misunderstanding MVVM. All your code belongs in the ViewModel, not in the code behind (there are a few exceptions). You should not be assigning DataContext in button handlers. It should be set once using something like the view locator pattern. Everything that the View gets from the ViewModel is done with data binding, not code in the code behind.
|
|
|
|
|
Hi..
Thanks for the reply.
But I have situation for getting search criteria from the page and perform the operation in the button click event based on passing the search criteria to the view model.
So, How can I get view's control value in the viewmodel?
Can u pls give a hint about how to overcome such type of situations?
Thanks..
|
|
|
|
|
The search criteria should be bound to a property on the VM. You then have the data in the VM, responding to the event (click the search or the key up/down) need to be handled.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Set the view's datacontext to the view model.
You could then apply commands to handle the button command click in the view model.
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.
|
|
|
|
|
Hello to All,
Can anyone can help me get data from the ViewModel(DataContext of the page) in Page's Code behind using MVVM architecture.
Thanks in Adv..
|
|
|
|
|
this.LayoutRoot.DataContext
This assumes the layoutroot has the data context assigned (otherwise just this.datacontext). You will also need to cast the datacontext back to your viewmodel
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
You should be setting the Datacontext of the page to the viewmodel somewhere if you are implementing MVVM correctly.
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.
|
|
|
|
|
One of the aspects of MVVM is that you don't have any code behind. The only thing thats "allowed" in the code behind is manipulating visuals. The fact that you want to interact with the ViewModel from the code behind is definitely wrong.
|
|
|
|
|
Hi,
can any one tell me how should i change the display of a combobox as a hyperlink, and when clicked on hyperlink it has to replace it by the combobox in the same place and display combobox item in the dropdown manner attached to the hyperlink...
|
|
|
|
|
This really sounds ugly, bleh
Use a datatemplate to create the comboboxitem with the HL
Create a second combo with standard formatting
You then have a number of events that need to be managed.
Click event on the HL
Do what you need with the data and set a property that makes the original CB collapsed and a second CB visible.
How you recover back to the original HL combo is a mystery you will need to unravel.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Yeah man, like Mycroft said... randomly changing a hyperlink <-> combobox is UGLY and not a very good UI IMO. Controls shouldn't randomly change types. It might make sense in your head, but it wouldn't make sense to a user.
|
|
|
|
|
I don't like the behavior of the datagrid when using the celltemplate and cell editting template elements of WPF.
<DataGridTemplateColumn
Header="Street Name"
Width="77">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock
Text="{Binding street}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox
Text="{Binding street, ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
You have to double tab to access the editing feature of the cell, you have to double click to edit it and it is when you use a combobox it gets even worse. Has anyone managed to make the DG usable? As it stands right now I need it, but I am almost embarrassed to release software with such erratic behavior. Does anyone have pointers on making this thing useful? My major issues are the double clicking issue with cellediting / celltemplate and the usability of a drop down:
<DataGridTemplateColumn
Header="State"
Width="60">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock
Text="{Binding PropertyState.name}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}},Path=DataContext.PropertyStates, ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="name"
SelectedValuePath="id"
SelectedValue="{Binding stateId}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
If this thing is a pain, is there a useful method of validating the datagrid without using the celltemplate / celleditingtemplate?
Cheers, --EA
|
|
|
|
|
Thats probably just how the control works by default. If you don't like the behavior, you can always change it . I'm guessing you want a single click to go into edit mode? My first approach would be to catch the single click and if the cell contains a control, put it into edit mode. Lots and lots of gotchas though. A text box should go into edit mode directly on the first click, but a combobox should only go into edit mode if you click the edit portion. I don't think it should go into edit mode if you click the drop down button. Or maybe it should? You need to play with it. You'll probably have to special case a few of the control types to get what you want. I.e. if the control is a text box do this, if you the control is a combobox, do this instead. Another gotcha I can see is if you catch the click too early, you'll "break" the controls. For example, a push button should be executed on release, not on click. The click on a button just gives it focus and captures mouse focus so you can mouse off the button with the mouse still pressed and come back and it'll get pressed again, etc.
|
|
|
|
|
Having read SH01s answer and the fact that you rarely see this type of question (editing in a SL datagrid) I feel it reinforces a design decision I have made and advocate.
NEVER USE A LIST CONTROL AS AN EDIT CONTROL
I apply the same rule to winforms, 99% of the time I use a dedicated edit form/control to do editing, either pop a dialog or have a dedicated details control on the form. The ONLY exception I allow is when the user need to edit 1 (and only 1) single cell of either textbox or checkbox.
The combobox in SL is such a PITA I would never even consider using it in a gridview. Change you design!
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
So in this instance of a workspace based WPF desktop application would you consider a master / details layout in order to edit a row as opposed to in row editing? I fail to see why it would be discouraged to use a control that has editing functionality to edit, especially when it improves the user experience when working as intended.
Still, as it is not working as intended it is what it is. It would have been much easier for the user to allow in place editing.
Thanks for the insight, though.
Cheers, --EA
|
|
|
|
|
I don't really agree with Mycroft that you shouldn't allow in place row editing. Thats silly. Thats EXACTLY what a data grid is for. If you go into Excel and can't edit cells, you would be thouroughly confused. Just do what I suggested in my other response and tweak the control to your liking.
|
|
|
|
|
I think it is ridiculous to have to create a workaround for a dysfunctional control. In this particular issue, the "New Row" behavior of a datagrid is so erratic that I am hesitant to use it. The editing of existing rows is easy enough, but the adding a new row is a pain in the butt that I am almost willing to mitigate the pain of by adding a small control on the screen to insert new rows into the datagrid.
Has anyone had success with new rows? My issue is primarily that the comboxbox / textbox cellediting template leaves the textbox blank when you choose an item from the combobox in the following code:
<DataGridTemplateColumn
Header="State"
Width="60">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock
Text="{Binding PropertyState.name}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}},Path=DataContext.PropertyStates, ValidatesOnDataErrors=True,UpdateSourceTrigger=PropertyChanged}"
DisplayMemberPath="name"
SelectedValuePath="id"
SelectedValue="{Binding stateId}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
After I choose an item from the drop down and leave the field it is a blank textbox.
|
|
|
|
|
Ok, first of all, before I get into your question, I'm guessing you haven't worked with WPF too long or extensively? Pretty much *ALL* the WPF controls are dysfunctional and immature when compared to the WinForms and Win32 versions. You have to remember that WPF controls are built from scratch from the ground up, not built on top of other technologies. I'm working on the ListView control at the moment because I needed to implement a lot of the missing features that came for free with the WinForms/Win32/MFC versions. So far, I've written about 3000 lines of C# code and about 1000 lines of XAML. That code is *NOT* sprinkled with 10 page comments or crazy white space or anything like that. That is ~4000 lines of straight up code to implement all the missing features in the ListView control. I would only need about 25% of this code if I was using Winforms or Win32. It sucks, sure, but thats part of playing with WPF . I'm sure MSFT will bring the controls up to snuff in the next few versions of WPF as some of the controls are missing really big features.
Anyways, with that being said...
Your template does look a bit suspicious to me, unless I'm missing something:
* Seems like you normally show PropertyState.name in the TextBlock
* Seems like your ComboBox shows a list of PropertyStates, displaying the name property with a property called stateId indicating the selected item
So...
1) you might want to get rid of the UpdateSourceTrigger=PropertyChanged and add Mode=TwoWay just to make sure that is working as expected... in certain situations the default values are different then what you might expect.
2) the big problem I see here is that assuming you are writing the combobox selection to stateId correctly as two-way, how exactly is the "PropertyState" and/or "PropertyState.name" notification happening? There isn't anything in your XAML that would indicate PropertyState.name is getting a notification change. I would think the ComboBox should write the selection to PropertyState no?
|
|
|
|
|
This is my first WPF project, you are correct there. I am not one hundred percent clear on the whole dependency property situation yet, so I am not entirely sure on how to update the PropertyState.name. Should I add an OnPropertyChanged("PropertyState") to the SelectedItem? I confess I am a little murky on one way - two way updates, the documentation for that has been vexing.
I will read more into it in hopes of scraping it together.
Cheers, --EA
|
|
|
|
|
Ok, well, theres basically two main ways you can tell the WPF data binding engine that something has changed.
1) Dependency Properties (or DP for short - the whole DependencyProperty.Register... mumbo jumbo)
2) INotifyPropertyChanged (or INPC for short)
These two methods are independent of each other. A DP doesn't use INPC and vice versa. A DP has its own infrastructure to notify of updates. INPC requires you to implement the PropertyChanged event and manually send out notifications.
Convention dictates that DPs are typically only used in controls and ViewModels use INPC.
DPs typically have C# get/set wrappers. It is important that the ONLY code you have there are the GetValue() and SetValue() calls. Thats it. Not one thing more. Not a single thing . Thats because only your code calls the getter & setter. The WPF infrastructure bypasses those completely. You don't want the user call and WPF doing different things.
With IPNC, WPF will call your C# get/set methods, so its consistent there.
Heres a link on binding modes: http://msdn.microsoft.com/en-us/library/system.windows.data.bindingmode.aspx
What is "PropertyState" in your view model? Is that a DP or INPC?
I would think at the very least, you need to change to SelectedValue="{Binding PropertyState}" on the combo box. Not sure at all what "stateId" is all about.
|
|
|
|
|
PropertyState is really neither. It is actually a linked table to the item "SelectedItem" which is of type property. So the datagrid is bound to public ObservableCollection<property>AllProperties and PropertyState would be SelectedItem.PropertyState.name on a row by row basis. So it has no public characteristics of it's own, but is rather exposed through the logical element Property.
Top of the datagrid:
<DataGrid
ItemsSource="{Binding AllProperties}"
AutoGenerateColumns="False"
SelectedItem="{Binding SelectedItem}"
GridLinesVisibility="Horizontal"
CanUserDeleteRows="False"
Grid.Row="0"
RowStyle="{StaticResource RowStyle}">
ViewModel Items:
public Property SelectedItem
{
get { return _selectedItem; }
set
{
if (value == null)
return;
_selectedItem = value;
OnPropertyChanged("SelectedItem");
}
}
private void LoadProperties()
{
var query = _db.Properties.Where(p => p.claimId == _claimId && p.active);
AllProperties = new ObservableCollection<Property>(query.ToList());
}
private void LoadStates()
{
var query = _db.PropertyStates;
PropertyStates = new ObservableCollection<PropertyState>(query.ToList());
}
Does that make enough sense? I realize it is kind of a mess. SelectedItem<property> is an INPC.
|
|
|
|
|
If your combobox is showing PropertyStates, the SelectedItem is going to be a PropertyState. So you need to have an INPC of PropertyState. Both the combobox and the textblock need to bind to that property.
|
|
|
|