Devxpress grid currency formatting - wpf

I'm using Devxpress v13.1 and not allowed to upgrade it.
I am trying to render a devxpress grid from a dataset. I want $400.0000 to display as $400.00 and can't get it to work.
I have the following code:
public MainWindow{
DataSet TransactionList = GetDataFromXML();// Loads XML to DS
TransactionGrid.ItemsSource = TransactionList.Tables[0];
TransactionGrid.CustomColumnDisplayText += TransactionGrid_CustomColumnDisplayText;
}
void TransactionGrid_CustomColumnDisplayText(object sender, DevExpress.Xpf.Grid.CustomColumnDisplayTextEventArgs e)
{
if (e.Column.FieldName == "Amount1")
{
//e.Column.DisplayTemplate =
e.DisplayText = String.Format("{0:0.00}", e.Value);
}
}
xaml code:
<dxg:GridControl Name="TransactionGrid" HorizontalAlignment="Left" Height="Auto" Width="Auto" >
<dxg:GridControl.View >
<dxg:TableView AllowEditing="False"></dxg:TableView>
</dxg:GridControl.View>
<dxg:GridControl.Columns>
<dxg:GridColumn FieldName="Amount1" Header="Amount1" Width="80" >
</dxg:GridColumn>
</dxg:GridControl.Columns>
</dxg:GridControl
>

I used the TGrid_CustomColumnDisplayText event to achieve the results. Trying to implement StringFormat="c2" didnt work at the xaml level. I had to Call the statement below in the constructor of the xaml page.
TGrid.CustomColumnDisplayText += TGrid_CustomColumnDisplayText;
Event is as below-
void Tgrid_CustomColumnDisplayText(object sender,
DevExpress.Xpf.Grid.CustomColumnDisplayTextEventArgs e)
{
CultureInfo ciUsa = new CultureInfo("en-US");
if (e.Column.FieldName == "Amount")
{
e.DisplayText = String.IsNullOrEmpty(e.Value.ToString()) ? String.Empty : String.Format(ciUsa, "{0:c2}", Convert.ToDecimal(e.Value));
}
}

Related

WPF TreeView Slow Loading

I have a tree view like this
<TreeView x:Name="tvFolders"
ItemsSource="{Binding TreeItems}"
Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
BorderBrush="{StaticResource ColligoBorderLightBrush}"
IsTextSearchCaseSensitive="False"
IsTextSearchEnabled="True"
VirtualizingPanel.VirtualizationMode="Recycling"
VirtualizingPanel.IsVirtualizing="True"
Loaded="tvFolders_Loaded">
</TreeView>
The binding TreeItems is an ObservableCollection.
If this tree is not very large, this works great but if I have many folders/subfolders structure it can take 10 seconds or so until it loads.
How do I solve the issue so tree is built faster?
Lazy loading can be done as mentioned below. Since it not good practice to post any links. I am posting links as well as code content in the link.
I got it from here. http://www.wpf-tutorial.com/treeview-control/lazy-loading-treeview-items/
<Grid>
<TreeView Name="trvStructure" TreeViewItem.Expanded="TreeViewItem_Expanded" Margin="10" />
</Grid>
public partial class LazyLoadingSample : Window
{
public LazyLoadingSample()
{
InitializeComponent();
DriveInfo[] drives = DriveInfo.GetDrives();
foreach(DriveInfo driveInfo in drives)
trvStructure.Items.Add(CreateTreeItem(driveInfo));
}
public void TreeViewItem_Expanded(object sender, RoutedEventArgs e)
{
TreeViewItem item = e.Source as TreeViewItem;
if((item.Items.Count == 1) && (item.Items[0] is string))
{
item.Items.Clear();
DirectoryInfo expandedDir = null;
if(item.Tag is DriveInfo)
expandedDir = (item.Tag as DriveInfo).RootDirectory;
if(item.Tag is DirectoryInfo)
expandedDir = (item.Tag as DirectoryInfo);
try
{
foreach(DirectoryInfo subDir in expandedDir.GetDirectories())
item.Items.Add(CreateTreeItem(subDir));
}
catch { }
}
}
private TreeViewItem CreateTreeItem(object o)
{
TreeViewItem item = new TreeViewItem();
item.Header = o.ToString();
item.Tag = o;
item.Items.Add("Loading...");
return item;
}
}

Silverlight Why doesn't this work

I am trying to create a slider(without binding).
Currently i did this:
Xaml:
<Slider Height="68" HorizontalAlignment="Left" Margin="52,45,0,0" x:Name="slider1" VerticalAlignment="Top" Width="256" Minimum="1" Maximum="40" Value="10" ValueChanged="slider1_ValueChanged" />
<TextBlock x:Name="textBlock1" Margin="52,120,0,0" Text="Slide it!" ></TextBlock>
And in my cs:
private void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) {
textBloxk1.FontSize = slider1.Value;
}
But the silverlight page keeps loading and won't show the slider, anyone know what I'm doing wrong??
Probably at first ValueChanged event, slider1 and textblock1 are still null.
try this:
private void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (textBlock1 != null && slider1 != null)
{
textBlock1.FontSize = slider1.Value;
}
}
look at your Xaml.. you setting value to 10 Value="10"... but at that time textBlock dosn't exist.. be carefull..
when parser parse Xaml it first create Slider then sets all values to slider (and fire all attached events), and only then it creates TextBlock...
so change you code to this, and everithing should be fine..
private void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (textBlock1 != null && slider1 != null)
{
textBlock1.FontSize = slider1.Value;
}
}

Problem Binding Url to listBox.itemsSource with XElement

Im trying to make dinamically loading url in a list Box by Binding.
Inicio.xaml.cs
void cardeek_DownloadUrlCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error != null) return;
textBox1.Text = e.Result;
XElement xmlUrl = XElement.Parse(e.Result);
listBox1.ItemsSource = from url in xmlUrl.Descendants("user")
select new TwitterItem { Url = url.Element("card").Element("url").Value, };
}
private void ContentPanel_Loaded(object sender, RoutedEventArgs e)
{
WebClient cardeekUrl = new WebClient();
cardeekUrl.DownloadStringCompleted += new DownloadStringCompletedEventHandler(cardeek_DownloadUrlCompleted);
cardeekUrl.DownloadStringAsync(new Uri("http://www.cardeek.com/wp7/response_url.php?email=" + "david.sonike#gmail.com" + "&code=" + "1"));
}
void cardeek_DownloadUrlCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error != null)
return;
textBox1.Text = e.Result;
XElement xmlUrl = XElement.Parse(e.Result);
listBox1.ItemsSource = from url in xmlUrl.Descendants("user")
select new TwitterItem
{
Url = url.Element("card").Element("url").Value,
};
}
private void ContentPanel_Loaded(object sender, RoutedEventArgs e)
{
WebClient cardeekUrl = new WebClient();
cardeekUrl.DownloadStringCompleted += new DownloadStringCompletedEventHandler(cardeek_DownloadUrlCompleted);
cardeekUrl.DownloadStringAsync(new Uri("http://www.cardeek.com/wp7/response_url.php?email=" + "david.sonike#gmail.com" + "&code=" + "1"));
}
Inicio.xaml
<ListBox Height="416" HorizontalAlignment="Left" Margin="41,191,0,0" Name="listBox1" VerticalAlignment="Top" Width="367">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Background="{Binding coItemBackground}">
<phone:WebBrowser HorizontalAlignment="Left" Margin="69,140,0,0" VerticalAlignment="Top" Height="121"
Width="137" Source="{Binding Url}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
and the Xml source in the web
www.marca.com
www.elmundo.com
www.vidaextra.com
In my Windows Phone 7 emulator cant see anything, anyone can help me solve the problem?¿
You are binding the Listbox to an Enumerable<TwitterItem>. As this doesn't implement INotifyPropertyChanged the UI isn't notified when you update the ItemSource in the callback.
As an alternative, consider creating an "ObservableCollection<TwitterItem> and binding to that. It automatically implements InotifyPropertyChanged so you don't need to.
You may also want to reconsider putting a WebBrowser inside the DataTemplate. There will be a performance cost of using it and it's unlikely to produce a good user experience.

WPF DataGrid: Blank Row Missing

I am creating a WPF window with a DataGrid, and I want to show the blank "new item" row at the bottom of the grid that allows me to add a new item to the grid. For some reason, the blank row is not shown on the grid on my window. Here is the markup I used to create the DataGrid:
<toolkit:DataGrid x:Name="ProjectTasksDataGrid"
DockPanel.Dock="Top"
Style="{DynamicResource {x:Static res:SharedResources.FsBlueGridKey}}"
AutoGenerateColumns="False"
ItemsSource="{Binding SelectedProject.Tasks}"
RowHeaderWidth="0"
MouseMove="OnStartDrag"
DragEnter="OnCheckDropTarget"
DragOver="OnCheckDropTarget"
DragLeave="OnCheckDropTarget"
Drop="OnDrop"
InitializingNewItem="ProjectTasksDataGrid_InitializingNewItem">
<toolkit:DataGrid.Columns>
<toolkit:DataGridCheckBoxColumn HeaderTemplate="{DynamicResource {x:Static res:SharedResources.CheckmarkHeaderKey}}" Width="25" Binding="{Binding Completed}" IsReadOnly="false"/>
<toolkit:DataGridTextColumn Header="Days" Width="75" Binding="{Binding NumDays}" IsReadOnly="false"/>
<toolkit:DataGridTextColumn Header="Due Date" Width="75" Binding="{Binding DueDate, Converter={StaticResource standardDateConverter}}" IsReadOnly="false"/>
<toolkit:DataGridTextColumn Header="Description" Width="*" Binding="{Binding Description}" IsReadOnly="false"/>
</toolkit:DataGrid.Columns>
</toolkit:DataGrid>
I can't figure out why the blank row isn't showing. I have tried the obvious stuff (IsReadOnly="false", CanUserAddRows="True"), with no luck. Any idea why the blank row is disabled? Thanks for your help.
You must also have to have a default constructor on the type in the collection.
Finally got back to this one. I am not going to change the accepted answer (green checkmark), but here is the cause of the problem:
My View Model wraps domain classes to provide infrastructure needed by WPF. I wrote a CodeProject article on the wrap method I use, which includes a collection class that has two type parameters:
VmCollection<VM, DM>
where DM is a wrapped domain class, and DM is the WPF class that wraps it.
It truns out that, for some weird reason, having the second type parameter in the collection class causes the WPF DataGrid to become uneditable. The fix is to eliminate the second type parameter.
Can't say why this works, only that it does. Hope it helps somebody else down the road.
Vincent Sibal posted an article describing what is required for adding new rows to a DataGrid. There are quite a few possibilities, and most of this depends on the type of collection you're using for SelectedProject.Tasks.
I would recommend making sure that "Tasks" is not a read only collection, and that it supports one of the required interfaces (mentioned in the previous link) to allow new items to be added correctly with DataGrid.
In my opinion this is a bug in the DataGrid. Mike Blandford's link helped me to finally realize what the problem is: The DataGrid does not recognize the type of the rows until it has a real object bound. The edit row does not appear b/c the data grid doesn't know the column types. You would think that binding a strongly typed collection would work, but it does not.
To expand upon Mike Blandford's answer, you must first assign the empty collection and then add and remove a row. For example,
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// data binding
dataGridUsers.ItemsSource = GetMembershipUsers();
EntRefUserDataSet.EntRefUserDataTable dt = (EntRefUserDataSet.EntRefUserDataTable)dataGridUsers.ItemsSource;
// hack to force edit row to appear for empty collections
if (dt.Rows.Count == 0)
{
dt.AddEntRefUserRow("", "", false, false);
dt.Rows[0].Delete();
}
}
Add an empty item to your ItemsSource and then remove it. You may have to set CanUserAddRows back to true after doing this. I read this solution here: (Posts by Jarrey and Rick Roen)
I had this problem when I set the ItemsSource to a DataTable's DefaultView and the view was empty. The columns were defined though so it should have been able to get them. Heh.
This happned to me , i forgot to new up the instance and it was nightmare for me . once i created an instance of the collection in onviewloaded it was solved.
`observablecollection<T> _newvariable = new observablecollection<T>();`
this solved my problem. hope it may help others
For me the best way to implement editable asynchronous DataGrid looks like that:
View Model:
public class UserTextMainViewModel : ViewModelBase
{
private bool _isBusy;
public bool IsBusy
{
get { return _isBusy; }
set
{
this._isBusy = value;
OnPropertyChanged();
}
}
private bool _isSearchActive;
private bool _isLoading;
private string _searchInput;
public string SearchInput
{
get { return _searchInput; }
set
{
_searchInput = value;
OnPropertyChanged();
_isSearchActive = !string.IsNullOrEmpty(value);
ApplySearch();
}
}
private ListCollectionView _translationsView;
public ListCollectionView TranslationsView
{
get
{
if (_translationsView == null)
{
OnRefreshRequired();
}
return _translationsView;
}
set
{
_translationsView = value;
OnPropertyChanged();
}
}
private void ApplySearch()
{
var view = TranslationsView;
if (view == null) return;
if (!_isSearchActive)
{
view.Filter = null;
}
else if (view.Filter == null)
{
view.Filter = FilterUserText;
}
else
{
view.Refresh();
}
}
private bool FilterUserText(object o)
{
if (!_isSearchActive) return true;
var item = (UserTextViewModel)o;
return item.Key.Contains(_searchInput, StringComparison.InvariantCultureIgnoreCase) ||
item.Value.Contains(_searchInput, StringComparison.InvariantCultureIgnoreCase);
}
private ICommand _clearSearchCommand;
public ICommand ClearSearchCommand
{
get
{
return _clearSearchCommand ??
(_clearSearchCommand =
new DelegateCommand((param) =>
{
this.SearchInput = string.Empty;
}, (p) => !string.IsNullOrEmpty(this.SearchInput)));
}
}
private async void OnRefreshRequired()
{
if (_isLoading) return;
_isLoading = true;
IsBusy = true;
try
{
var result = await LoadDefinitions();
TranslationsView = new ListCollectionView(result);
}
catch (Exception ex)
{
//ex.HandleError();//TODO: Needs to create properly error handling
}
_isLoading = false;
IsBusy = false;
}
private async Task<IList> LoadDefinitions()
{
var translatioViewModels = await Task.Run(() => TranslationRepository.Instance.AllTranslationsCache
.Select(model => new UserTextViewModel(model)).ToList());
return translatioViewModels;
}
}
XAML:
<UserControl x:Class="UCM.WFDesigner.Views.UserTextMainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:model="clr-namespace:Cellebrite.Diagnostics.Model.Entities;assembly=Cellebrite.Diagnostics.Model"
xmlns:System="clr-namespace:System;assembly=mscorlib"
xmlns:converters1="clr-namespace:UCM.Infra.Converters;assembly=UCM.Infra"
xmlns:core="clr-namespace:UCM.WFDesigner.Core"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300">
<DockPanel>
<StackPanel Orientation="Horizontal"
DockPanel.Dock="Top"
HorizontalAlignment="Left">
<DockPanel>
<TextBlock Text="Search:"
DockPanel.Dock="Left"
VerticalAlignment="Center"
FontWeight="Bold"
Margin="0,0,5,0" />
<Button Style="{StaticResource StyleButtonDeleteCommon}"
Height="20"
Width="20"
DockPanel.Dock="Right"
ToolTip="Clear Filter"
Command="{Binding ClearSearchCommand}" />
<TextBox Text="{Binding SearchInput, UpdateSourceTrigger=PropertyChanged}"
Width="500"
VerticalContentAlignment="Center"
Margin="0,0,2,0"
FontSize="13" />
</DockPanel>
</StackPanel>
<Grid>
<DataGrid ItemsSource="{Binding Path=TranslationsView}"
AutoGenerateColumns="False"
SelectionMode="Single"
CanUserAddRows="True">
<DataGrid.Columns>
<!-- your columns definition is here-->
</DataGrid.Columns>
</DataGrid>
<!-- your "busy indicator", that shows to user a message instead of stuck data grid-->
<Border Visibility="{Binding IsBusy,Converter={converters1:BooleanToSomethingConverter TrueValue='Visible', FalseValue='Collapsed'}}"
Background="#50000000">
<TextBlock Foreground="White"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Text="Loading. . ."
FontSize="16" />
</Border>
</Grid>
</DockPanel>
This pattern allows to work with data grid in a quite simple way and code is very simple either.
Do not forget to create default constructor for class that represents your data source.

Problem databinding a custom control in silverlight

I'm attempting to databind a custom control in Silverlight 3 and I'm getting strange problems with it.
My xaml for the user control is this:
<UserControl x:Class="StronicoMain.GenericSmallIcon"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400" Height="300" >
<Canvas x:Name="canGSI">
</Canvas>
</UserControl>
The codebehind for the user control is this
private string _EntityTypeID;
public string EntityTypeID
{
get
{
return _EntityTypeID;
}
set
{
_EntityTypeID = value;
}
}
public GenericSmallIcon()
{
InitializeComponent();
Loaded += new RoutedEventHandler(Page_Loaded);
}
public void Page_Loaded(object sender, RoutedEventArgs e)
{
icoMale icoMale = new icoMale();
icoFemale icoFem = new icoFemale();
if (EntityTypeID == null)
{
canGSI.Children.Add(icoMale);
}
else if (EntityTypeID == "1")
{
canGSI.Children.Add(icoMale);
}
else if (EntityTypeID == "2")
{
canGSI.Children.Add(icoFem);
}
else
{
canGSI.Children.Add(icoMale);
}
}
I'm calling it from the DataGridSelection Adapter (taken from the Microsoft Toolkit example page for AutoCompleteBox-Datagrid version) - the relevant portion looks like this:
<Stron:DataGridSelectionAdapter x:Name="SelectionAdapter" AutoGenerateColumns="False" IsReadOnly="False">
<Stron:DataGridSelectionAdapter.Columns>
<data:DataGridTemplateColumn>
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate><Stron:GenericSmallIcon EntityTypeID="{Binding EntityTypeID}"></Stron:GenericSmallIcon></DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>
<data:DataGridTextColumn Header="Contact Name" FontWeight="Bold" Foreground="#CC000000" Binding="{Binding EntityName}" />
<data:DataGridTextColumn Header="Tags" Binding="{Binding EntityTags}" />
</Stron:DataGridSelectionAdapter.Columns>
</Stron:DataGridSelectionAdapter>
I run the code, and I get the error "ManagedRuntimeError #4004" - if I try to use the custom control while manually setting the databinding it works just fine, if I try to rely on the values that are being databound I get the error. How can I create a custom databound event on a custom control? I think that is the problem, that the page is loading before the values are passed to it.
Thanks everyone.
~Steve
Update, here is the working, changed code as per the accepted answer
public static readonly DependencyProperty EntityTypeIDProperty = DependencyProperty.Register("EntityTypeID", typeof(string), typeof(GenericSmallIcon), new PropertyMetadata(new PropertyChangedCallback(GenericSmallIcon.OnEntityTypeIDPropertyChanged)));
public string EntityTypeID
{
get { return (string)GetValue(EntityTypeIDProperty); }
set { SetValue(EntityTypeIDProperty, value); }
}
private static void OnEntityTypeIDPropertyChanged(
DependencyObject d, DependencyPropertyChangedEventArgs e)
{
GenericSmallIcon control = d as GenericSmallIcon;
string b = (string)e.NewValue;
}
This is invalid:
<Stron:GenericSmallIcon EntityTypeID="{Binding EntityTypeID}"/>
The problem is that you cannot bind to a Property that is not a Dependency Property. See this MSDN article about turning your POCO Property into a Dependency property.
-Mark

Resources