Search Results

Search found 75 results on 3 pages for 'selectionmode'.

Page 3/3 | < Previous Page | 1 2 3 

  • Binding WPF DataGrid to DataTable using TemplateColumns

    - by Chris J
    I have tried everything and got nowhere so I'm hoping someone can give me the aha moment. I simply cannot get the binding to pull the data in the datagrid successfully. I have a DataTable that contains multiple columns with of MyDataType} public class MyData { string nameData {get;set;} boolean showData {get;set;} } MyDataType has 2 properties (A string, a boolean) I have created a test DataTable DataTable GetDummyData() { DataTable dt = new DataTable("Foo"); dt.Columns.Add(new DataColumn("AnotherColumn", typeof(MyData))); dt.Rows.Add(new MyData("Row1C1", true)); dt.Rows.Add(new MyData("Row2C1", false)); dt.AcceptChanges(); return dt; } I have a WPF DataGrid which I want to show my DataTable. But all I want to do is to change how each cell is rendered to show [TextBlock][Button] per cell with values bound to the MyData object and this is where I'm having a tonne of trouble. My XAML looks like this <Window.Resources><ResourceDictionary><DataTemplate x:Key="MyDataTemplate" DataType="MyData"> <StackPanel Orientation="Horizontal" > <Button Background="Green" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="5,0,0,0" Content="{Binding Path=nameData}"></Button> <TextBlock Background="Green" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5,0,0,0" Text="{Binding Path=nameData}"></TextBlock> </StackPanel> </DataTemplate></ResourceDictionary></Window.Resources> <Grid> <dg:DataGrid Grid.Row="1" AutoGenerateColumns="True" x:Name="dataGrid1" SelectionMode="Single" CanUserAddRows="False" CanUserSortColumns="true" CanUserDeleteRows="False" AlternatingRowBackground="AliceBlue" AutoGeneratingColumn="dataGrid1_AutoGeneratingColumn" ItemsSource="{Binding}" /> now all I do once loaded is to attempt to bind the DataTable to the WPF DataGrid dt = GetDummyData(); dataGrid1.ItemsSource = dt.DefaultView; The TextBlock and Button show up, but they don't bind, which leaves them blank. Could anyone let me know if they have any idea how to fix this. This should be simple, thats what Microsoft leads us to believe. I have set the Column.CellTemplate during the AutoGenerating event and still get no binding. Please help!!!

    Read the article

  • Nested AccordionItem. Inner AccordionItem do not expand.

    - by Ali
    In Silverlight an AccordionItem is inside another one . When the inner one is selected, it can not expand its parent more which is already expanded to show its own content. I tried to get around it by templating but I was unlucky. Does any one has a solution for it [prefer a solution without code]? <UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:layoutPrimitivesToolkit="clr-namespace:System.Windows.Controls.Primitives;assembly=System.Windows.Controls.Layout.Toolkit" xmlns:layoutToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Layout.Toolkit" xmlns:controlsToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="NestedAccordion_Silverlight.MainPage" Width="640" Height="480"> <Grid x:Name="LayoutRoot" Background="White"> <layoutToolkit:Accordion BorderBrush="#FF00FF53" SelectionMode="ZeroOrMore"> <layoutToolkit:AccordionItem Header="Header" VerticalAlignment="Top" > <StackPanel VerticalAlignment="Top"> <TextBlock TextWrapping="Wrap" Text="Some content"/> <Button Content="Button" Width="75"/> <layoutToolkit:AccordionItem Header="Inner Accordion1" VerticalAlignment="Top" > <StackPanel VerticalAlignment="Top"> <TextBlock TextWrapping="Wrap" Text="Some content"/> <Button Content="Button" Width="75"/> </StackPanel> </layoutToolkit:AccordionItem> </StackPanel> </layoutToolkit:AccordionItem> <layoutToolkit:AccordionItem Header="Header" VerticalAlignment="Top" > <StackPanel> <TextBlock TextWrapping="Wrap" Text="Some content"/> <Button Content="Button" Width="75"/> </StackPanel> </layoutToolkit:AccordionItem> <layoutToolkit:AccordionItem Header="Header" VerticalAlignment="Top" > <StackPanel> <TextBlock TextWrapping="Wrap" Text="Some content"/> <Button Content="Button" Width="75"/> </StackPanel> </layoutToolkit:AccordionItem> </layoutToolkit:Accordion> </Grid> Is it a bug or I am in a wrong path?

    Read the article

  • Mouse scroll not working in a scroll viewer with a wpf datagrid and additional UI elements

    - by paladugu457
    I am trying to figure out how to get the mouse scroll working on a wpf window with a scrollviewer and a datagrid within it. The WPF and C# code is below <ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto"> <Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Grid Grid.Row="0"> <Border Name="DataGridBorder" BorderThickness="2" Margin="1" CornerRadius="4" BorderBrush="#FF080757"> <dg:DataGrid AutoGenerateColumns="False" Name="ValuesDataGrid" BorderThickness="0" CanUserResizeColumns="True" FontWeight="Bold" HorizontalScrollBarVisibility="Auto" CanUserReorderColumns="False" IsReadOnly="True" IsTextSearchEnabled="True" AlternationCount="2" SelectionMode="Extended" GridLinesVisibility="All" HeadersVisibility="Column" CanUserAddRows="False" CanUserDeleteRows="False" CanUserResizeRows="False" CanUserSortColumns="False" RowDetailsVisibilityMode="Collapsed" SelectedIndex="0" RowStyle="{StaticResource CognitiDataGridRowStyle}" > <dg:DataGrid.Columns> <dg:DataGridTemplateColumn Header="Title" > <dg:DataGridTemplateColumn.CellTemplate> <DataTemplate> <StackPanel Orientation="Horizontal" > <TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding Path=Name}" FontWeight="Normal" /> </StackPanel> </DataTemplate> </dg:DataGridTemplateColumn.CellTemplate> </dg:DataGridTemplateColumn> </dg:DataGrid.Columns> </dg:DataGrid> </Border> </Grid> <Button Grid.Row="1" Height="90" >hello world</Button> </Grid> </ScrollViewer> and the C# code is as follows public partial class Window1 : Window { public Window1() { InitializeComponent(); initialize(); } public void initialize() { ObservableCollection<MyObject> testList = new ObservableCollection<MyObject>(); for (int i = 0; i < 20; i++) { MyObject my = new MyObject("jack " + i); testList.Add(my); } ValuesDataGrid.ItemsSource = testList; } } public class MyObject { public string Name { get; set; } public MyObject(string name) { Name = name; } } The problem i am facing is that when using the mouse to scroll, it works fine when it is over the button but as soon as i move the mouse pointer over the grid and try to scroll, nothing happens. I am able to move the scrollbar of the scrollviewer directly though. I am still a wpf novice so any help on how to get the mouse scroll to work over the datagrid would be appreciated. I am guessing there should be a pretty easy solution for this but I havent been able to figure it out

    Read the article

  • WPF ListView Data Binding wont synchronize

    - by Aviatrix
    my listview will display only the item that its added by the constructor and it wont add the items that i add dynamically public class PostList : ObservableCollection<PostData> { public PostList() : base() { Add(new PostData("Isak", "Dinesen")); // Add(new PostData("Victor", "Hugo")); // Add(new PostData("Jules", "Verne")); } public void AddToList (string[] data){ string username2, msg; msg = data[0]; username2 = data[1]; Add(new PostData(msg, username2)); } } public class PostData { private string Username; private string Msg; private string Avatar; private string LinkAttached; private string PicAttached; private string VideoAttached; public PostData(string msg ,string username, string avatar=null, string link=null,string pic=null ,string video=null) { this.Username = username; this.Msg = msg; this.Avatar = avatar; this.LinkAttached = link; this.PicAttached = pic; this.VideoAttached = video; } public string pMsg { get { return Msg; } set { Msg = value; } } public string pUsername { get { return Username; } set { Username = value; } } ..... ..... } Xaml <ListView x:Name="PostListView" BorderThickness="0" MinHeight="300" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="{x:Null}" VerticalContentAlignment="Top" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" IsSynchronizedWithCurrentItem="True" MinWidth="332" SelectedIndex="0" SelectionMode="Extended" AlternationCount="1" ItemsSource="{Binding Source={StaticResource PostListData}}"> <ListView.ItemTemplate> <DataTemplate> <DockPanel x:Name="SinglePost" VerticalAlignment="Top" ScrollViewer.CanContentScroll="True" ClipToBounds="True" Width="333" Height="70" d:LayoutOverrides="VerticalAlignment" d:IsEffectDisabled="True"> <StackPanel x:Name="AvatarNickHolder" Width="60"> <Label x:Name="Nick" HorizontalAlignment="Center" Margin="5,0" VerticalAlignment="Top" Height="15" Content="{Binding Path=pUsername}" FontFamily="Arial" FontSize="10.667" Padding="5,0"/> <Image x:Name="Avatar" HorizontalAlignment="Center" Margin="5,0,5,5" VerticalAlignment="Top" Width="50" Height="50" IsHitTestVisible="False" Source="1045443356IMG_0972.jpg" Stretch="UniformToFill"/> </StackPanel> <TextBlock x:Name="userPostText" Margin="0,0,5,0" VerticalAlignment="Center" FontSize="10.667" Text="{Binding Path=pMsg}" TextWrapping="Wrap"/> </DockPanel> </DataTemplate> </ListView.ItemTemplate> </ListView>

    Read the article

  • Binding Source suspends itself when I don't want it to.

    - by Scott Chamberlain
    I have two data tables set up in a Master-Details configuration with a relation "Ticket_CallSegments" between them. I also have two Binding Sources and a Data Grid View configured like this (Init Code) // // dgvTickets // this.dgvTickets.AllowUserToAddRows = false; this.dgvTickets.AllowUserToDeleteRows = false; this.dgvTickets.AllowUserToResizeRows = false; this.dgvTickets.AutoGenerateColumns = false; this.dgvTickets.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; this.dgvTickets.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] { this.cREATEDATEDataGridViewTextBoxColumn, this.contactFullNameDataGridViewTextBoxColumn, this.pARTIALNOTEDataGridViewTextBoxColumn}); this.dgvTickets.DataSource = this.ticketsDataSetBindingSource; this.dgvTickets.Dock = System.Windows.Forms.DockStyle.Fill; this.dgvTickets.Location = new System.Drawing.Point(0, 0); this.dgvTickets.MultiSelect = false; this.dgvTickets.Name = "dgvTickets"; this.dgvTickets.ReadOnly = true; this.dgvTickets.RowHeadersVisible = false; this.dgvTickets.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect; this.dgvTickets.Size = new System.Drawing.Size(359, 600); this.dgvTickets.TabIndex = 0; // // ticketsDataSetBindingSource // this.ticketsDataSetBindingSource.DataMember = "Ticket"; this.ticketsDataSetBindingSource.DataSource = this.ticketsDataSet; this.ticketsDataSetBindingSource.CurrentChanged += new System.EventHandler(this.ticketsDataSetBindingSource_CurrentChanged); // // callSegementBindingSource // this.callSegementBindingSource.DataMember = "Ticket_CallSegments"; this.callSegementBindingSource.DataSource = this.ticketsDataSetBindingSource; this.callSegementBindingSource.Sort = "CreateDate"; //Function to update a rich text box. private void ticketsDataSetBindingSource_CurrentChanged(object sender, EventArgs e) { StringBuilder sb = new StringBuilder(); rtbTickets.Clear(); foreach (DataRowView drv in callSegementBindingSource) { TicketsDataSet.CallSegmentsRow row = (TicketsDataSet.CallSegmentsRow)drv.Row; sb.AppendLine("**********************************"); sb.AppendLine(String.Format("CreateDate: {1}, Created by: {0}", row.USERNAME, row.CREATEDATE)); sb.AppendLine("**********************************"); rtbTickets.SelectionFont = new Font("Arial", (float)11, FontStyle.Bold); rtbTickets.SelectedText = sb.ToString(); rtbTickets.SelectionFont = new Font("Arial", (float)11, FontStyle.Regular); rtbTickets.SelectedText = row.NOTES + "\n\n"; } } However when ticketsDataSetBindingSource_CurrentChanged gets called when I select a new row in my Data Grid View callSegementBindingSource.IsBindingSuspended is set to true and my text box does not update correctly (it seems to always pull from the same row in CallSegments). Can anyone see what I am doing wrong or tell me how to unsuspend the binding so it will pull the correct data?

    Read the article

  • WinRT ControlTemplate ItemsPanel

    - by user1427149
    I'm new to WinRT and am trying to create a standard gridview which has a group heading with a number of tiles beneath it. That bit is easy. I'm trying to modify it so that beneath the grid of tiles I can also add a footer using the containers style: <GridView x:Name="itemGridView" AutomationProperties.AutomationId="ItemGridView" AutomationProperties.Name="Grouped Items" Margin="116,0,40,46" ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}" ItemTemplate="{StaticResource Project200x200ItemTemplate}" SelectionMode="None" IsItemClickEnabled="True" ItemClick="ItemView_ItemClick"> <GridView.ItemsPanel> <ItemsPanelTemplate> <VirtualizingStackPanel Orientation="Horizontal"/> </ItemsPanelTemplate> </GridView.ItemsPanel> <GridView.GroupStyle> <GroupStyle> <GroupStyle.HeaderTemplate> <DataTemplate> <Grid Margin="1,0,0,6"> <Button AutomationProperties.Name="Group Title" Content="{Binding Name}" Click="Header_Click" Style="{StaticResource TextButtonStyle}" FontWeight="{Binding IsSelected, ConverterParameter=FontWeight, Converter={StaticResource BooleanToFontWeightConverter}}" /> </Grid> </DataTemplate> </GroupStyle.HeaderTemplate> <GroupStyle.Panel> <ItemsPanelTemplate> <VariableSizedWrapGrid Background="Red" Orientation="Vertical" Margin="0,0,40,0" /> </ItemsPanelTemplate> </GroupStyle.Panel> <GroupStyle.ContainerStyle> <Style TargetType="GroupItem"> <Setter Property="Template"> <Setter.Value> <ControlTemplate> <StackPanel> <ContentPresenter/> <ItemsPresenter/> <TextBlock Text="*** End of group ***"/> </StackPanel> </ControlTemplate> </Setter.Value> </Setter> </Style> </GroupStyle.ContainerStyle> </GroupStyle> </GridView.GroupStyle> </GridView> This almost works but after adding the container style, the grid of tiles no longer shows... the group header and 'End of group' textblock is showing, but I've lost the tile grid. Can anyone spot what I'm doing wrong...?

    Read the article

  • Binding using ElementName for a control within the Grid\ListView

    - by i2nfo
    Hi I am currently busy with a WPF application that uses a "GridView". There are several template columns one of which is a ComboBox in column 3 named cmbInputControlType. What I would like to do using my Converter class, which I have already created, is binding the visibility of the TextBox(txtFrom) in column 4 to the selected value of the ComboBox(Column 3). Basically if you select a value from the the ComboBox(cmbInputControlType - column 3), it must update teh visibility of the TextBox(txtFrom - column 4) <ListView Height="150" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto" Width="435" HorizontalAlignment="Center" Margin="5,0,5,5" Name="lstInput" VerticalAlignment="Top" SelectionMode="Single" HorizontalContentAlignment="Left"> <ListView.Resources> <local:InputControlTypeConverter x:Key="InputConType" /> </ListView.Resources> <ListView.View> <GridView> <!--Column 1--> <GridViewColumn Header="ParameterName" x:Name="lblParameterName" DisplayMemberBinding="{Binding ParameterName}" Width="100" /> <!--Column 2--> <GridViewColumn Header="DisplayName"> <GridViewColumn.CellTemplate> <DataTemplate> <TextBox x:Name="txtDisplayName" Width="150" /> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <!--Column 3--> <GridViewColumn Header="ControlType"> <GridViewColumn.CellTemplate> <DataTemplate> <ComboBox x:Name="cmbInputControlType" Width="100" SelectionChanged="cmbInputControlType_SelectionChanged" > <ComboBoxItem Content="TextBox" /> <ComboBoxItem Content="Copy" /> </ComboBox> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <!--Column 4--> <GridViewColumn Header="From"> <GridViewColumn.CellTemplate> <DataTemplate> <TextBox x:Name="txtCopyFrom" Width="150" Visibility="{Binding ElementName=cmbInputControlType,Path=SelectedItem, Converter={StaticResource InputConType}}" /> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <!--Column 5--> <GridViewColumn Header="To"> <GridViewColumn.CellTemplate> <DataTemplate> <TextBox x:Name="txtCopyTo" Width="150" /> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> </GridView> </ListView.View> </ListView>

    Read the article

  • is there any way we can disable on mouse over event on certain columns of an data grid

    - by prince23
    hi, here wat i am trying to do is that on mouse over of first column i need to hit mouse MouseEnter event and show the pop up which i have kept there rest all other column i dnt need to to show the pop up so i am having this fuction there MouseLeave="Row_MouseLeave" <sdk:DataGrid MinHeight="100" x:Name="dgCounty" AutoGenerateColumns="False" VerticalAlignment="Top" Grid.Row="1" IsReadOnly="True" Margin="5,5,5,0" RowDetailsVisibilityChanged="dgCounty_RowDetailsVisibilityChanged" SelectionMode="Extended" RowDetailsVisibilityMode="VisibleWhenSelected" MouseEnter="dgCounty_MouseEnter" MouseLeave="dgCounty_MouseLeave" SelectionChanged="dgCounty_SelectionChanged" LoadingRow="dgCounty_LoadingRow1" UnloadingRow="dgCounty_UnloadingRow"> <sdk:DataGrid.Columns> <sdk:DataGridTemplateColumn> <sdk:DataGridTemplateColumn.CellTemplate> <DataTemplate> <Button x:Name="myButton" Width="24" Height="24" Click="Details_Click"> <Image x:Name="img" Source="Images/detail.JPG" Stretch="None"/> </Button> </DataTemplate> </sdk:DataGridTemplateColumn.CellTemplate> </sdk:DataGridTemplateColumn> <sdk:DataGridTemplateColumn Header="ID"> <sdk:DataGridTemplateColumn.CellTemplate> <DataTemplate > <sdk:Label Content="{Binding EmployeeID}" /> </DataTemplate> </sdk:DataGridTemplateColumn.CellTemplate> </sdk:DataGridTemplateColumn> <sdk:DataGridTemplateColumn Header="Name"> <sdk:DataGridTemplateColumn.CellTemplate> <DataTemplate > <sdk:Label Content="{Binding EmployeeFName}" MouseLeave="Row_MouseLeave" /> </DataTemplate> </sdk:DataGridTemplateColumn.CellTemplate> </sdk:DataGridTemplateColumn> <sdk:DataGridTemplateColumn Header="MailID"> <sdk:DataGridTemplateColumn.CellTemplate> <DataTemplate > <sdk:Label Content="{Binding EmployeeMailID}" MouseLeave="Row_MouseLeave" /> </DataTemplate> </sdk:DataGridTemplateColumn.CellTemplate> </sdk:DataGridTemplateColumn> </sdk:DataGrid.Columns> </sdk:DataGrid> in code behind void Row_MouseLeave(object sender, MouseEventArgs e) { Show.Visibility = Visibility.Collapsed; PoPGrid.Visibility = Visibility.Collapsed; } void Row_MouseEnter(object sender, MouseEventArgs e) { } the pop up her is like the ajax modal pop up wat we do in asp.net i am able to show data in pop up now the main issue is i need to show pop up only on the 2 column. rest all other column i need to hide the pop up when i move mouse over on that column. i am trying this concept it is not working is there any way i can achive it as i said only need to show pop up on mouse over of the 2 column thanks in advance prince

    Read the article

  • how to bind the image dynamically for datagrid in.cs

    - by prince23
    hi, this is my xaml code. <sdk:DataGrid x:Name="dgMarks" CanUserResizeColumns="False" SelectionMode="Single" AutoGenerateColumns="False" VerticalAlignment="Top" IsReadOnly="True" Margin="13,44,0,0" RowDetailsVisibilityChanged="dgMarks_RowDetailsVisibilityChanged" RowDetailsVisibilityMode="Collapsed" Height="391" HorizontalAlignment="Left" Width="965" SelectionChanged="dgMarks_SelectionChanged" VerticalScrollBarVisibility="Visible" > <sdk:DataGrid.Columns> <sdk:DataGridTemplateColumn> <sdk:DataGridTemplateColumn.CellTemplate> <DataTemplate> <Button x:Name="myButton" Click="ExpandMarks_Click"> <TextBlock Text="{Binding Level}" TextWrapping="NoWrap" ></TextBlock> <Image x:Name="imgMarks" Stretch="None"/> </Button> </DataTemplate> </sdk:DataGridTemplateColumn.CellTemplate> </sdk:DataGridTemplateColumn> <sdk:DataGridTemplateColumn Header="Name" Visibility="Collapsed"> <sdk:DataGridTemplateColumn.CellTemplate> <DataTemplate > <sdk:Label Content="{Binding Name}"/> </DataTemplate> </sdk:DataGridTemplateColumn.CellTemplate> </sdk:DataGridTemplateColumn> <sdk:DataGridTemplateColumn Header="Marks" Width="80"> <sdk:DataGridTemplateColumn.CellTemplate> <DataTemplate> <sdk:Label Content="{Binding Marks}"/> </DataTemplate> </sdk:DataGridTemplateColumn.CellTemplate> </sdk:DataGridTemplateColumn> </sdk:DataGrid.Columns> </sdk:DataGrid> from database i am getting these values name marks Level abc 23 0 xyz 67 1 yu 56 0 aa 89 1 here i am binding these values for datagrid. i have an tricky thing to be done .based on the level i should be binding image if level value is 1 then bind the image. if level value is 0 then do not bind the image for that row i know this is how we need to handle but where should i write this code in which events? Image imgLevel = (Image)templateTrendScore.FindName("imgMarks"); if (level1==1) { imgLevel .Source = new BitmapImage(new Uri("/Images/image1.JPG", UriKind.Relative)); } any help would be great thanks in advance

    Read the article

  • Item index of Binding element

    - by vibeeshanRC
    I am creating a XAML / C# WinRT App and i have a collection of collection and i am binding it to a Grid-view(collections as groups ) Now i have to color the background of the GridViewItem according to their index in the collection (Dark color for the first one and light color for the last one ) How can i implement using a converter. (if there are 6 collections with 10 items all the first item will the dark and the 10 the item will be lighter). Simply: How can i send the item-index property to the converter as a parameter. My XAML <GridView x:Name="Grid1" ItemsSource="{Binding}" ItemTemplateSelector="{StaticResource templateSelector}" SelectionMode="None" > <GridView.ItemsPanel> <ItemsPanelTemplate> <VirtualizingStackPanel Orientation="Horizontal" VirtualizingStackPanel.VirtualizationMode="Recycling"/> </ItemsPanelTemplate> </GridView.ItemsPanel> <GridView.GroupStyle> <GroupStyle HidesIfEmpty="True"> <GroupStyle.HeaderTemplate> <DataTemplate> <Grid Margin="0,0,0,0"> <TextBlock Text='{Binding Name}' Margin="5" /> </Grid> </DataTemplate> </GroupStyle.HeaderTemplate> <GroupStyle.ContainerStyle> <Style TargetType="GroupItem" > <Setter Property="BorderThickness" Value="0"/> <Setter Property="Margin" Value="0,0"/> </Style> </GroupStyle.ContainerStyle> <GroupStyle.Panel> <ItemsPanelTemplate> <VariableSizedWrapGrid/> </ItemsPanelTemplate> </GroupStyle.Panel> </GroupStyle> </GridView.GroupStyle> </GridView> .......... <converters:MyConverter x:Key="templateSelector" Temp1="{StaticResource Temp1}" Temp2="{StaticResource Temp2}" > </converters:MyConverter> <DataTemplate x:Key="Temp1"> <Grid > <Grid> <Grid.Resources> <converters:PanelBackgroundColorConverter x:Name="panelBackgroundColorConverter" Key="{Binding}"/> <Grid.Resources/> <Grid.Background> <Binding Path="MPath" Converter="{StaticResource panelBackgroundColorConverter}" ConverterParameter="sym"/> </Grid.Background> <Grid/> <DataTemplate/>

    Read the article

  • How do I change the visual style of a listitem based on its bound value?

    - by Rodd
    I have a listbox (here's the xaml): <ListBox MinWidth="300" ItemsSource="{Binding Relationships, Mode=OneWay}" SelectedItem="{Binding SelectedRelationship, Mode=TwoWay}" SelectionMode="Single" HorizontalAlignment="Left" > <ListBox.ItemTemplate> <DataTemplate> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> <RowDefinition/> <RowDefinition/> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <CheckBox IsChecked = "{Binding IsPrimary}" IsHitTestVisible="False" /> <StackPanel Orientation="Horizontal" Grid.Column="1"> <TextBlock Text="{Binding RelationshipType}" FontWeight="Bold" Margin="0,0,5,0" /> <TextBlock Text="{Binding Status}" FontStyle="Italic" /> </StackPanel> <TextBlock Text="{Binding UnitName}" Grid.Row="1" Grid.Column="1" /> <TextBlock Text="{Binding StartDate, Converter={StaticResource DateConverter}}" Grid.Row="2" Grid.Column="1"/> <TextBlock Text="{Binding RetireDate}" Grid.Row="3" Grid.Column="1" /> <TextBlock Text="{Binding EndDate}" Grid.Row="4" Grid.Column="1" /> <TextBlock Text="{Binding ReasonForLeaving}" Grid.Row="5" Grid.Column="1" /> </Grid> </DataTemplate> </ListBox.ItemTemplate> </ListBox> What I want to do is have each item in the listbox have one of 3 backgrounds (green if the value of IsPrimary = true, Orange if the EndDate value is empty and grey if the EndDate value is not empty. Is there a way to template the listbox items so that they evaluate bound items to determine a view state or to have each listbox item bind to a value that I can set for each item in my viewmodel? Thanks for your help.

    Read the article

  • why is that we always get an extra column show in datagrid

    - by prince23
    hi, i have four columns specfied but why is that i always see one extra column shown in the output this is my xaml code <Grid x:Name="LayoutRoot" Background="White" Height="492" Width="453"> <sdk:DataGrid MinHeight="100" x:Name="dgCounty" AutoGenerateColumns="False" VerticalAlignment="Top" Grid.Row="1" IsReadOnly="True" Margin="5,5,5,0" RowDetailsVisibilityChanged="dgCounty_RowDetailsVisibilityChanged" SelectionMode="Extended" RowDetailsVisibilityMode="VisibleWhenSelected"> <sdk:DataGrid.Columns> <sdk:DataGridTemplateColumn> <sdk:DataGridTemplateColumn.CellTemplate> <DataTemplate> <Button x:Name="myButton" Width="24" Height="24" Click="Details_Click"> <Image x:Name="img" Source="Images/detail.JPG" Stretch="None"/> </Button> </DataTemplate> </sdk:DataGridTemplateColumn.CellTemplate> </sdk:DataGridTemplateColumn> <sdk:DataGridTemplateColumn Header="ID"> <sdk:DataGridTemplateColumn.CellTemplate> <DataTemplate > <sdk:Label Content="{Binding EmployeeID}" /> </DataTemplate> </sdk:DataGridTemplateColumn.CellTemplate> </sdk:DataGridTemplateColumn> <sdk:DataGridTemplateColumn Header="Name"> <sdk:DataGridTemplateColumn.CellTemplate> <DataTemplate > <sdk:Label Content="{Binding EmployeeFName}" /> </DataTemplate> </sdk:DataGridTemplateColumn.CellTemplate> </sdk:DataGridTemplateColumn> <sdk:DataGridTemplateColumn Header="MailID"> <sdk:DataGridTemplateColumn.CellTemplate> <DataTemplate > <sdk:Label Content="{Binding EmployeeMailID}" /> </DataTemplate> </sdk:DataGridTemplateColumn.CellTemplate> </sdk:DataGridTemplateColumn> </sdk:DataGrid.Columns> </sdk:DataGrid> is there any setting that we need to do to remove that extra column? thanks in advance for the help.

    Read the article

  • dojo dgrid tree, subrows in wrong position

    - by Ventura
    I have a dgrid, working with tree column plugin. Every time that the user click on the tree, I call the server, catch the subrows(json) and bind it. But when it happens, these subrows are show in wrong position, like the image bellow. The most strange is when I change the pagination, after go back to first page, the subrows stay on the correct place. (please, tell me if is possible to understand my english, then I can try to improve the text) My dgrid code: var CustomGrid = declare([OnDemandGrid, Keyboard, Selection, Pagination]); var grid = new CustomGrid({ columns: [ selector({label: "#", disabled: function(object){ return object.type == 'DOCx'; }}, "radio"), {label:'Id', field:'id', sortable: false}, tree({label: "Title", field:"title", sortable: true, indentWidth:20, allowDuplicates:true}), //{label:'Title', field:'title', sortable: false}, {label:'Count', field:'count', sortable: false} ], store: this.memoryStore, collapseOnRefresh:true, pagingLinks: false, pagingTextBox: true, firstLastArrows: true, pageSizeOptions: [10, 15, 25], selectionMode: "single", // for Selection; only select a single row at a time cellNavigation: false // for Keyboard; allow only row-level keyboard navigation }, "grid"); My memory store: loadMemoryStore: function(items){ this.memoryStore = Observable(new Memory({ data: items, getChildren: function(parent, options){ return this.query({parent: parent.id}, options); }, mayHaveChildren: function(parent){ return (parent.count != 0) && (parent.type != 'DOC'); } })); }, This moment I am binding the subrows: success: function(data){ for(var i=0; i<data.report.length; i++){ this.memoryStore.put({id:data.report[i].id, title:data.report[i].created, type:'DOC', parent:this.designId}); } }, I was thinking, maybe every moment that I bind the subrows, I could do like a refresh on the grid, maybe works. I think that the pagination does the same thing. Thanks. edit: I forgot the question. Well, How can I correct this bug? If The refresh in dgrid works. How can I do it? Other thing that I was thinking, maybe my getChildren is wrong, but I could not identify it. thanks again.

    Read the article

  • WPF DataGrid does not scoll on drag

    - by Greg R
    I have a strange problem with a WPF DataGrid from WPF Toolkit. The scrollbars appear correctly when the number of rows grows, and the scrolling works when you press up or down arrows on the scrollbar. The problem comes in when I try to drag the scrollbar on the datagrid. My page has a scroll viewer around it. When I click and drag the scrollbar on the grid, it scrolls the page scroller instead. If the scrollbar does not apear on the page, there grid still does not scroll. Is there a workaround for this??? Would really appreciate some help with this issue! For example, in this case if the page is < 280, it scrolls on drag. But drag scrolling does not work on the grid. <ScrollViewer ScrollViewer.IsDeferredScrollingEnabled="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" > <DockPanel> <dg:DataGrid HorizontalScrollBarVisibility="Auto" SelectionMode="Single" CanUserAddRows="False" CanUserDeleteRows="False" CanUserResizeColumns="False" CanUserSortColumns="False" AutoGenerateColumns="False" RowHeaderWidth="17" ItemsSource="{Binding Path=OrderSearchVm}" IsReadOnly="True" MaxHeight="280" DockPanel.Dock="Top"> <dg:DataGrid.Columns> <dg:DataGridTextColumn Width="75" Header="Date" Binding="{Binding Path=OrderDate}" > <dg:DataGridTextColumn.ElementStyle> <Style TargetType="{x:Type TextBlock}"> <Setter Property="TextWrapping" Value="Wrap" /> </Style> </dg:DataGridTextColumn.ElementStyle> </dg:DataGridTextColumn> <dg:DataGridTextColumn Header="Type" Binding="{Binding Path=OrderType}" Width="45"/> <dg:DataGridTextColumn Header="Shipping Name" Binding="{Binding Path=ShipToName}" Width="115"> <dg:DataGridTextColumn.ElementStyle> <Style TargetType="{x:Type TextBlock}"> <Setter Property="TextWrapping" Value="Wrap" /> </Style> </dg:DataGridTextColumn.ElementStyle> </dg:DataGridTextColumn> <dg:DataGridTextColumn Header="Shipping Address " Binding="{Binding Path=ShipToAddress}" Width="160"> <dg:DataGridTextColumn.ElementStyle> <Style TargetType="{x:Type TextBlock}"> <Setter Property="TextWrapping" Value="Wrap" /> </Style> </dg:DataGridTextColumn.ElementStyle> </dg:DataGridTextColumn> <dg:DataGridTextColumn Header="E-Mail" Binding="{Binding Path=Email}" Width="140"> <dg:DataGridTextColumn.ElementStyle> <Style TargetType="{x:Type TextBlock}"> <Setter Property="TextWrapping" Value="Wrap" /> </Style> </dg:DataGridTextColumn.ElementStyle> </dg:DataGridTextColumn> </dg:DataGrid.Columns> </dg:DataGrid> </DockPanel> </ScrollViewer>

    Read the article

  • WPF ListBox/View Data Binding weird result

    - by Aviatrix
    I have this problem when i try to synchronize a observable list with listbox/view it displays the first item X times (x total amount of records in the list) but it doesn't change the variable's here is the XAML <ListBox x:Name="PostListView" BorderThickness="0" MinHeight="300" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="{x:Null}" VerticalContentAlignment="Top" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" DataContext="{Binding Source={StaticResource PostListData}}" ItemsSource="{Binding Mode=OneWay}" IsSynchronizedWithCurrentItem="True" MinWidth="332" SelectedIndex="0" SelectionMode="Extended" AlternationCount="1"> <ListBox.ItemTemplate> <DataTemplate> <DockPanel x:Name="SinglePost" VerticalAlignment="Top" ScrollViewer.CanContentScroll="True" ClipToBounds="True" Width="333" Height="70" d:LayoutOverrides="VerticalAlignment" d:IsEffectDisabled="True"> <DockPanel.DataContext> <local:PostList/> </DockPanel.DataContext> <StackPanel x:Name="AvatarNickHolder" Width="60"> <Label x:Name="Nick" HorizontalAlignment="Center" Margin="5,0" VerticalAlignment="Top" Height="15" Content="{Binding Path=pUsername, FallbackValue=pUsername}" FontFamily="Arial" FontSize="10.667" Padding="5,0"/> <Image x:Name="Avatar" HorizontalAlignment="Center" Margin="5,0,5,5" VerticalAlignment="Top" Width="50" Height="50" IsHitTestVisible="False" Source="1045443356IMG_0972.jpg" Stretch="UniformToFill"/> </StackPanel> <TextBlock x:Name="userPostText" Margin="0,0,5,0" VerticalAlignment="Center" FontSize="10.667" Text="{Binding Path=pMsg, FallbackValue=pMsg}" TextWrapping="Wrap"/> </DockPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> and here is the ovservable list class public class PostList : ObservableCollection<PostData> { public PostList() : base() { Add(new PostData("this is test msg", "Cather", "1045443356IMG_0972.jpg")); Add(new PostData("this is test msg1", "t1", "1045443356IMG_0972.jpg")); Add(new PostData("this is test msg2", "t2", "1045443356IMG_0972.jpg")); Add(new PostData("this is test msg3", "t3", "1045443356IMG_0972.jpg")); Add(new PostData("this is test msg4", "t4", "1045443356IMG_0972.jpg")); Add(new PostData("this is test msg5", "t5", "1045443356IMG_0972.jpg")); // Add(new PostData("Isak", "Dinesen")); // Add(new PostData("Victor", "Hugo")); // Add(new PostData("Jules", "Verne")); } } public class PostData { private string Username; private string Msg; private string Avatar; private string LinkAttached; private string PicAttached; private string VideoAttached; public PostData(string msg ,string username, string avatar=null, string link=null,string pic=null ,string video=null) { this.Username = username; this.Msg = msg; this.Avatar = avatar; this.LinkAttached = link; this.PicAttached = pic; this.VideoAttached = video; } public string pMsg { get { return Msg; } set { Msg = value; } } public string pUsername { get { return Username; } set { Username = value; } } public string pAvatar { get { return Avatar; } set { Avatar = value; } } public string pLink { get { return LinkAttached; } set { LinkAttached = value; } } public string pPic { get { return PicAttached; } set { PicAttached = value; } } public string pVideo { get { return VideoAttached; } set { VideoAttached = value; } } } Any ideas ?

    Read the article

  • WPF Xaml Custom Styling Selected Item Style in a ListBox

    - by John Batdorf
    I have a list box that scrolls images horizontally. I have the following XAML I used blend to create it. It originally had a x:Key on the Style TaregetType line, MSDN said to remove it, as I was getting errors on that. Now I'm getting this error: Error 3 Operation is not valid while ItemsSource is in use. Access and modify elements with ItemsControl.ItemsSource instead. I don't understand how to apply all of this junk that way, I've tried several thing, nothing is working. My goal is to have the selected item's background be white, not blue. Seems like a lot of work for something so small! Thanks. <ListBox ItemsSource="{Binding Source={StaticResource WPFApparelCollection}}" Grid.Row="1" Margin="2,26,2,104" ScrollViewer.VerticalScrollBarVisibility="Hidden" ScrollViewer.HorizontalScrollBarVisibility="Hidden" SelectionMode="Single" x:Name="list1" MouseLeave="List1_MouseLeave" MouseMove="List1_MouseMove" Style="{DynamicResource ListBoxStyle1}" > <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="Background" Value="Transparent"/> <Setter Property="HorizontalContentAlignment" Value="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/> <Setter Property="VerticalContentAlignment" Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/> <Setter Property="Padding" Value="2,0,0,0"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListBoxItem}"> <Border x:Name="Bd" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"> <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> </Border> <ControlTemplate.Triggers> <Trigger Property="IsSelected" Value="true"> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/> <Setter Property="Background" TargetName="Bd" Value="#FFFFFFFF"/> </Trigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsSelected" Value="true"/> <Condition Property="Selector.IsSelectionActive" Value="false"/> </MultiTrigger.Conditions> <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> </MultiTrigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <ListBox.ItemsPanel> <ItemsPanelTemplate> <VirtualizingStackPanel Orientation="Horizontal" IsItemsHost="True" /> </ItemsPanelTemplate> </ListBox.ItemsPanel> <ListBox.ItemTemplate> <DataTemplate> <Image Source="{Binding Image}" /> </DataTemplate> </ListBox.ItemTemplate> </ListBox>

    Read the article

  • Changing color of HighlighBrushKey in XAML

    - by phil
    Hi, I have the following problem. The background color in a ListView is set LightGreen or White, whether a boolflag is true or false. Example Screen Window1.xaml: <Window.Resources> <Style TargetType="{x:Type ListViewItem}"> <Style.Triggers> <DataTrigger Binding="{Binding Path=BoolFlag}" Value="True"> <Setter Property="Background" Value="LightGreen" /> </DataTrigger> </Style.Triggers> </Style> </Window.Resources> <StackPanel> <ListView ItemsSource="{Binding Path=Personen}" SelectionMode="Single" SelectionChanged="ListViewSelectionChanged"> <ListView.View> <GridView> <GridViewColumn DisplayMemberBinding="{Binding Path=Vorname}" Header="Vorname" /> <GridViewColumn DisplayMemberBinding="{Binding Path=Nachname}" Header="Nachname" /> <GridViewColumn DisplayMemberBinding="{Binding Path=Alter}" Header="Alter" /> <GridViewColumn DisplayMemberBinding="{Binding Path=BoolFlag}" Header="BoolFlag" /> </GridView> </ListView.View> </ListView> </StackPanel> Window1.xaml.cs: public partial class Window1 : Window { private IList<Person> _personen = new List<Person>(); public Window1() { _personen.Add(new Person { Vorname = "Max", Nachname = "Mustermann", Alter = 18, BoolFlag = false, }); _personen.Add(new Person { Vorname = "Karl", Nachname = "Mayer", Alter = 27, BoolFlag = true, }); _personen.Add(new Person { Vorname = "Josef", Nachname = "Huber", Alter = 38, BoolFlag = false, }); DataContext = this; InitializeComponent(); } public IList<Person> Personen { get { return _personen; } } private void ListViewSelectionChanged(object sender, SelectionChangedEventArgs e) { Person person = e.AddedItems[0] as Person; if (person != null) { if (person.BoolFlag) { this.Resources[SystemColors.HighlightBrushKey] = Brushes.Green; } else { this.Resources[SystemColors.HighlightBrushKey] = Brushes.RoyalBlue; } } } } Person.cs: public class Person { public string Vorname { get; set; } public string Nachname { get; set; } public int Alter { get; set; } public bool BoolFlag { get; set; } } Now I want to set the highlight color of the selected item, depending on the boolflag. In Code-Behind I do this with: private void ListViewSelectionChanged(object sender, SelectionChangedEventArgs e) { Person person = e.AddedItems[0] as Person; if (person != null) { if (person.BoolFlag) { this.Resources[SystemColors.HighlightBrushKey] = Brushes.Green; } else { this.Resources[SystemColors.HighlightBrushKey] = Brushes.RoyalBlue; } } } } This works fine, but now I want to define the code above in the XAML-file. With <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Green" /> I can overwrite the default-value. However, it works, but the color is set to Green for all selected items. I have tried different ways to switch the color of HighlightBrushKey between Green and Blue in XAML, depending on the boolflag, but I didn't succeed. May you can help me and give me some examples?

    Read the article

  • WPF: Binding to ListBoxItem.IsSelected doesn't work for off-screen items

    - by Qwertie
    In my program I have a set of view-model objects to represent items in a ListBox (multi-select is allowed). The viewmodel has an IsSelected property that I would like to bind to the ListBox so that selection state is managed in the viewmodel rather than in the listbox itself. However, apparently the ListBox doesn't maintain bindings for most of the off-screen items, so in general the IsSelected property is not synchronized correctly. Here is some code that demonstrates the problem. First XAML: <StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock>Number of selected items: </TextBlock> <TextBlock Text="{Binding NumItemsSelected}"/> </StackPanel> <ListBox ItemsSource="{Binding Items}" Height="200" SelectionMode="Extended"> <ListBox.ItemContainerStyle> <Style TargetType="{x:Type ListBoxItem}"> <Setter Property="IsSelected" Value="{Binding IsSelected}"/> </Style> </ListBox.ItemContainerStyle> </ListBox> <Button Name="TestSelectAll" Click="TestSelectAll_Click">Select all</Button> </StackPanel> C# Select All handler: private void TestSelectAll_Click(object sender, RoutedEventArgs e) { foreach (var item in _dataContext.Items) item.IsSelected = true; } C# viewmodel: public class TestItem : NPCHelper { TestDataContext _c; string _text; public TestItem(TestDataContext c, string text) { _c = c; _text = text; } public override string ToString() { return _text; } bool _isSelected; public bool IsSelected { get { return _isSelected; } set { _isSelected = value; FirePropertyChanged("IsSelected"); _c.FirePropertyChanged("NumItemsSelected"); } } } public class TestDataContext : NPCHelper { public TestDataContext() { for (int i = 0; i < 200; i++) _items.Add(new TestItem(this, i.ToString())); } ObservableCollection<TestItem> _items = new ObservableCollection<TestItem>(); public ObservableCollection<TestItem> Items { get { return _items; } } public int NumItemsSelected { get { return _items.Where(it => it.IsSelected).Count(); } } } public class NPCHelper : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public void FirePropertyChanged(string prop) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(prop)); } } Two separate problems can be observed. If you click the first item and then press Shift+End, all 200 items should be selected; however, the heading reports that only 21 items are selected. If you click "Select all" then all items are indeed selected. If you then click an item in the ListBox you would expect the other 199 items to be deselected, but this does not happen. Instead, only the items that are on the screen (and a few others) are deselected. All 199 items will not be deselected unless you first scroll through the list from beginning to end (and even then, oddly enough, it doesn't work if you perform scrolling with the little scroll box). My questions are: Can someone explain precisely why this occurs? Can I avoid or work around the problem?

    Read the article

  • Primefaces: java.lang.ClassCastException: java.util.HashMap cannot be cast to ClassObject

    - by razegarra
    I have a problem with p:dataTable in Primefaces, I can not find the error. Class UsuarioAsig: public class UsuarioAsig { private BigDecimal codigopersona; private String nombre; private String paterno; private String materno; private String login; private String observacion; private String tipocontrol; private String externo; private String habilitado; private String nombreperfil; private BigDecimal codigousuario; ...get and set...} Class UsuarioAsigListaDataModel: public class UsuarioAsigListaDataModel extends ListDataModel<UsuarioAsig> implements SelectableDataModel<UsuarioAsig> { public UsuarioAsigListaDataModel(){} public UsuarioAsigListaDataModel(List<UsuarioAsig> data){super(data);} @Override public UsuarioAsig getRowData(String rowKey) { @SuppressWarnings("unchecked") List<UsuarioAsig> listaUsuarioAsigLectura = (List<UsuarioAsig>) getWrappedData(); for (UsuarioAsig usuarioAsig : listaUsuarioAsigLectura) { if (usuarioAsig.getCodigopersona().equals(rowKey)) { return usuarioAsig; } } return null; } @Override public Object getRowKey(UsuarioAsig usuarioAsig) { return usuarioAsig.getCodigopersona(); }} Controller UsuarioAsigController: @Controller("usuarioAsigController") @Scope(value = "session") public class UsuarioAsigController { private List<UsuarioAsig> listaUsuarioAsig; private HashMap<String, Object> selUsuarioAsig; private UsuarioAsigListaDataModel mediumUsuarioAsigModel; @Autowired UsuarioService usuarioService; ... public List<UsuarioAsig> getListaUsuarioAsig() { listaUsuarioAsig = usuarioService.selectAsig(); return listaUsuarioAsig; } public void setListaUsuarioAsig(List<UsuarioAsig> listaUsuarioAsig) { this.listaUsuarioAsig = listaUsuarioAsig; } public void setMediumUsuarioAsigModel(UsuarioAsigListaDataModel mediumUsuarioAsigModel) { this.mediumUsuarioAsigModel = mediumUsuarioAsigModel; } public UsuarioAsigListaDataModel getMediumUsuarioAsigModel() { listaUsuarioAsig = usuarioService.selectAsig(); mediumUsuarioAsigModel = new UsuarioAsigListaDataModel(listaUsuarioAsig); return mediumUsuarioAsigModel; } public void onRowSelect(SelectEvent event) { FacesMessage msg = new FacesMessage("Usuario seleccionado", ((UsuarioAsig) event.getObject()).getNombre()); FacesContext.getCurrentInstance().addMessage(null, msg); } } the error is generated when you click on one of the lines of datatable: asiginst.xhtml: <h:form id="form"> <p:growl id="msgs" showDetail="true" /> <p:dataTable id="usuarioAsigListaDataModel" var="usuarioAsig" value="#{usuarioAsigController.mediumUsuarioAsigModel}" rowKey="#{usuarioAsig.codigopersona}" selection="#{usuarioAsigController.selUsuarioAsig}" selectionMode="single" paginator="true" rows="10"> <p:ajax event="rowSelect" listener="#{usuarioAsigController.onRowSelect}" update=":form:msgs" /> <p:column headerText="Código" style="width:10%">#{usuarioAsig.codigopersona}</p:column> <p:column headerText="Nombre" style="width:32%">#{usuarioAsig.nombre}</p:column> <p:column headerText="Apellidos" style="width:32%">#{usuarioAsig.paterno} #{usuarioasig.materno}</p:column> <p:column headerText="Tipo Control" style="width:20%">#{usuarioAsig.tipocontrol}</p:column> <p:column headerText="Habilitado" style="width:6%">#{usuarioAsig.habilitado}</p:column> </p:dataTable> </h:form> THE ERROR IS GENERATED: WARNING: asiginst.xhtml @51,103 listener="#{usuarioAsigController.onRowSelect}": java.lang.ClassCastException: java.util.HashMap cannot be cast to com.datos.entidades.qry.UsuarioAsig javax.el.ELException: asiginst.xhtml @51,103 listener="#{usuarioAsigController.onRowSelect}": java.lang.ClassCastException: java.util.HashMap cannot be cast to com.datos.entidades.qry.UsuarioAsig at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:111) at org.primefaces.behavior.ajax.AjaxBehaviorListenerImpl.processArgListener(AjaxBehaviorListenerImpl.java:69) at org.primefaces.behavior.ajax.AjaxBehaviorListenerImpl.processAjaxBehavior(AjaxBehaviorListenerImpl.java:56) at org.primefaces.event.SelectEvent.processListener(SelectEvent.java:40) at javax.faces.component.behavior.BehaviorBase.broadcast(BehaviorBase.java:102) at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:760) at javax.faces.component.UIData.broadcast(UIData.java:1071) at javax.faces.component.UIData.broadcast(UIData.java:1093) at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794) at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259) at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:409) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:722) Caused by: java.lang.ClassCastException: java.util.HashMap cannot be cast to com.datos.entidades.qry.UsuarioAsig at com.controller.UsuarioAsigController.onRowSelect(UsuarioAsigController.java:217) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.apache.el.parser.AstValue.invoke(AstValue.java:264) at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278) at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105) ... 29 more

    Read the article

  • CheckBox ListView SelectedValues DependencyProperty Binding

    - by Ristogod
    I am writing a custom control that is a ListView that has a CheckBox on each item in the ListView to indicate that item is Selected. I was able to do so with the following XAML. <ListView x:Class="CheckedListViewSample.CheckBoxListView" 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" mc:Ignorable="d"> <ListView.Style> <Style TargetType="{x:Type ListView}"> <Setter Property="SelectionMode" Value="Multiple" /> <Style.Resources> <Style TargetType="ListViewItem"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ListViewItem"> <Border BorderThickness="{TemplateBinding Border.BorderThickness}" Padding="{TemplateBinding Control.Padding}" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}" SnapsToDevicePixels="True"> <CheckBox IsChecked="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}}"> <CheckBox.Content> <ContentPresenter Content="{TemplateBinding ContentControl.Content}" ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" /> </CheckBox.Content> </CheckBox> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </Style.Resources> </Style> </ListView.Style> </ListView> I however am trying to attempt one more feature. The ListView has a SelectedItems DependencyProperty that returns a collection of the Items that are checked. However, I need to implement a SelectedValues DependencyProperty. I also am implementing a SelectedValuesPath DependencyProperty. By using the SelectedValuesPath, I indicate the path where the values are found for each selected item. So if my items have an ID property, I can specify using the SelectedValuesPath property "ID". The SelectedValues property would then return a collection of ID values. I have this working also using this code in the code-behind: using System.Windows; using System.Windows.Controls; using System.ComponentModel; using System.Collections; using System.Collections.Generic; namespace CheckedListViewSample { /// <summary> /// Interaction logic for CheckBoxListView.xaml /// </summary> public partial class CheckBoxListView : ListView { public static DependencyProperty SelectedValuesPathProperty = DependencyProperty.Register("SelectedValuesPath", typeof(string), typeof(CheckBoxListView), new PropertyMetadata(string.Empty, null)); public static DependencyProperty SelectedValuesProperty = DependencyProperty.Register("SelectedValues", typeof(IList), typeof(CheckBoxListView), new PropertyMetadata(new List<object>(), null)); [Category("Appearance")] [Localizability(LocalizationCategory.NeverLocalize)] [Bindable(true)] public string SelectedValuesPath { get { return ((string)(base.GetValue(CheckBoxListView.SelectedValuesPathProperty))); } set { base.SetValue(CheckBoxListView.SelectedValuesPathProperty, value); } } [Bindable(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [Category("Appearance")] public IList SelectedValues { get { return ((IList)(base.GetValue(CheckBoxListView.SelectedValuesPathProperty))); } set { base.SetValue(CheckBoxListView.SelectedValuesPathProperty, value); } } public CheckBoxListView() : base() { InitializeComponent(); base.SelectionChanged += new SelectionChangedEventHandler(CheckBoxListView_SelectionChanged); } private void CheckBoxListView_SelectionChanged(object sender, SelectionChangedEventArgs e) { List<object> values = new List<object>(); foreach (var item in SelectedItems) { if (string.IsNullOrWhiteSpace(SelectedValuesPath)) { values.Add(item); } else { try { values.Add(item.GetType().GetProperty(SelectedValuesPath).GetValue(item, null)); } catch { } } } base.SetValue(CheckBoxListView.SelectedValuesProperty, values); e.Handled = true; } } } My problem is that my binding only works one way right now. I'm having trouble trying to figure out how to implement my SelectedValues DependencyProperty so that I could Bind a Collection of values to it, and when the control is loaded, the CheckBoxes are checked with items that have values that correspond to the SelectedValues. I've considered using the PropertyChangedCallBack event, but can't quite figure out how I could write that to achieve my goal. I'm also unsure of how I find the correct ListViewItem to set it as Selected. And lastly, if I can find the ListViewItem and set it to be Selected, won't that fire my SelectionChanged event each time I set a ListViewItem to be Selected?

    Read the article

  • LevelToVisibilityConverter in silverligt 4

    - by prince23
    <UserControl x:Class="SLGridImage.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"> <UserControl.Resources> <local:LevelToVisibilityConverter x:Key="LevelToVisibility" /> </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="White"> <sdk:DataGrid x:Name="dgMarks" CanUserResizeColumns="False" SelectionMode="Single" AutoGenerateColumns="False" VerticalAlignment="Top" ItemsSource="{Binding MarkCollection}" IsReadOnly="True" Margin="13,44,0,0" RowDetailsVisibilityMode="Collapsed" Height="391" HorizontalAlignment="Left" Width="965" VerticalScrollBarVisibility="Visible" > <sdk:DataGrid.Columns> <sdk:DataGridTemplateColumn> <sdk:DataGridTemplateColumn.CellTemplate> <DataTemplate> <Button x:Name="myButton" Click="myButton_Click"> <StackPanel Orientation="Horizontal"> <Image Margin="2, 2, 2, 2" x:Name="imgMarks" Stretch="Fill" Width="12" Height="12" Source="Images/test.png" VerticalAlignment="Center" HorizontalAlignment="Center" Visibility="{Binding Level, Converter={StaticResource LevelToVisibility}}" /> <TextBlock Text="{Binding Level}" TextWrapping="NoWrap" ></TextBlock> </StackPanel> </Button> </DataTemplate> </sdk:DataGridTemplateColumn.CellTemplate> </sdk:DataGridTemplateColumn> <sdk:DataGridTemplateColumn Header="Name" > <sdk:DataGridTemplateColumn.CellTemplate> <DataTemplate > <Border> <TextBlock Text="{Binding Name}" /> </Border> </DataTemplate> </sdk:DataGridTemplateColumn.CellTemplate> </sdk:DataGridTemplateColumn> <sdk:DataGridTemplateColumn Header="Marks" Width="80"> <sdk:DataGridTemplateColumn.CellTemplate> <DataTemplate> <Border> <TextBlock Text="{Binding Marks}" /> </Border> </DataTemplate> </sdk:DataGridTemplateColumn.CellTemplate> </sdk:DataGridTemplateColumn> </sdk:DataGrid.Columns> </sdk:DataGrid> </Grid> </UserControl> in .cs using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.Collections.ObjectModel; using System.ComponentModel; namespace SLGridImage { public partial class MainPage : UserControl { private MarksViewModel model = new MarksViewModel(); public MainPage() { InitializeComponent(); this.DataContext = model; } private void myButton_Click(object sender, RoutedEventArgs e) { } } public class MarksViewModel : INotifyPropertyChanged { public MarksViewModel() { markCollection.Add(new Mark() { Name = "ABC", Marks = 23, Level = 0 }); markCollection.Add(new Mark() { Name = "XYZ", Marks = 67, Level = 1 }); markCollection.Add(new Mark() { Name = "YU", Marks = 56, Level = 0 }); markCollection.Add(new Mark() { Name = "AAA", Marks = 89, Level = 1 }); } private ObservableCollection<Mark> markCollection = new ObservableCollection<Mark>(); public ObservableCollection<Mark> MarkCollection { get { return this.markCollection; } set { this.markCollection = value; OnPropertyChanged("MarkCollection"); } } public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string propName) { if (PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs(propName)); } } public class Mark { public string Name { get; set; } public int Marks { get; set; } public int Level { get; set; } } public class LevelToVisibilityConverter : System.Windows.Data.IValueConverter { #region IValueConverter Members public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { Visibility isVisible = Visibility.Collapsed; if ((value == null)) return isVisible; int condition = (int)value; isVisible = condition == 1 ? Visibility.Visible : Visibility.Collapsed; return isVisible; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } #endregion } } when i run getting error The type 'local:LevelToVisibilityConverter' was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built. what i am i missing here looking forward for an solution thank you

    Read the article

  • listbox isSelected databinding in DataTemplate

    - by Kinmarui
    I try to simply databind IsSelected property with IsSelected field in my class. But after I change the value in code its doesn't change the property, neither does clicking on ListBoxItem change the field value. XAML: <FlipView ItemsSource="{Binding Source={StaticResource itemsViewSource}}" ... > <FlipView.ItemTemplate> <DataTemplate> <UserControl Loaded="StartLayoutUpdates" Unloaded="StopLayoutUpdates"> <!-- other controls --> <ListBox Grid.Row="1" Grid.ColumnSpan="3" SelectionMode="Multiple" VerticalAlignment="Center" ItemsSource="{Binding Answers}"> <ListBox.Resources> <local:LogicToText x:Key="logToText" /> </ListBox.Resources> <!-- bind IsSelected only in one way from code to content --> <ItemsControl.ItemTemplate> <DataTemplate> <ListBoxItem IsSelected="{Binding IsSelected, Mode=TwoWay, Converter={StaticResource logToText}}" Content="{Binding IsSelected, Mode=TwoWay, Converter={StaticResource logToText}}"> </ListBoxItem> </DataTemplate> </ItemsControl.ItemTemplate> <!-- not working at all <ListBox.Resources> <Style TargetType="ListBoxItem"> <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/> <Setter Property="Content" Value="{Binding IsSelected, Mode=TwoWay}"/> </Style> </ListBox.Resources>--> </ListBox> </UserControl> </DataTemplate> </FlipView.ItemTemplate> </FlipView> Code: Answers private ObservableCollection<PrawoJazdyDataAnswer> _answers = new ObservableCollection<PrawoJazdyDataAnswer>(); public ObservableCollection<PrawoJazdyDataAnswer> Answers { get { return this._answers; } } Single item(Answer) public class PrawoJazdyDataAnswer : NPCHelper// PrawoJazdy.Common.BindableBase { public PrawoJazdyDataAnswer(String ans, bool ansb) { this._ans = ans; this._isSelected = ansb; } public override string ToString() { return _isSelected.ToString(); } //Only For debug purposes normally return _ans; private string _ans; public string Ans { get { return this._ans; } //set { this.SetProperty(ref this._ans, value); } } private bool _isSelected; public bool IsSelected { get { return this._isSelected; } set { _isSelected = value; FirePropertyChanged("IsSelected"); //this.SetProperty(ref this._isSelected, value); } } } FirePropertyChanged public class NPCHelper : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public void FirePropertyChanged(string prop) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(prop)); } } Converter(which sometimes seems to be needed and others not..., I tried ~10 approaches from different tutorials/examples) public class LogicToText : IValueConverter { /// <summary> /// /// </summary> public object Convert(object value, Type targetType, object parameter, string language) { //if (value == null || (bool)value == false) // return "False"; return value.ToString(); } /// <summary> /// /// </summary> public object ConvertBack(object value, Type targetType, object parameter, string language) { return value.ToString().Contains("True") ? true : false; } Thanks in advance, and sorry for my English(still learning). @edit Thanks for quick reply. For test purposes i created a button and text block: It's in other controls part (above list box, but in FlipView) <Button Click="spr" >Sprawdz</Button> <TextBlock Text="{Binding Answers[0].IsSelected, Mode=TwoWay}" > </TextBlock> Click method private void spr(object sender, RoutedEventArgs e) { var ans = ((PrawoJazdyDataQuestion)this.flipView.SelectedItem).Answers; foreach (var item in ans) item.IsSelected = item.IsSelected ? false : true; } As I wrote when i'm changing data from code side its change text, but not appearance of ListBoxItem, and if i just select it on ListBox its doesn't change the date i textblock neither in ListBox itself.

    Read the article

  • Using jQuery to POST Form Data to an ASP.NET ASMX AJAX Web Service

    - by Rick Strahl
    The other day I got a question about how to call an ASP.NET ASMX Web Service or PageMethods with the POST data from a Web Form (or any HTML form for that matter). The idea is that you should be able to call an endpoint URL, send it regular urlencoded POST data and then use Request.Form[] to retrieve the posted data as needed. My first reaction was that you can’t do it, because ASP.NET ASMX AJAX services (as well as Page Methods and WCF REST AJAX Services) require that the content POSTed to the server is posted as JSON and sent with an application/json or application/x-javascript content type. IOW, you can’t directly call an ASP.NET AJAX service with regular urlencoded data. Note that there are other ways to accomplish this. You can use ASP.NET MVC and a custom route, an HTTP Handler or separate ASPX page, or even a WCF REST service that’s configured to use non-JSON inputs. However if you want to use an ASP.NET AJAX service (or Page Methods) with a little bit of setup work it’s actually quite easy to capture all the form variables on the client and ship them up to the server. The basic steps needed to make this happen are: Capture form variables into an array on the client with jQuery’s .serializeArray() function Use $.ajax() or my ServiceProxy class to make an AJAX call to the server to send this array On the server create a custom type that matches the .serializeArray() name/value structure Create extension methods on NameValue[] to easily extract form variables Create a [WebMethod] that accepts this name/value type as an array (NameValue[]) This seems like a lot of work but realize that steps 3 and 4 are a one time setup step that can be reused in your entire site or multiple applications. Let’s look at a short example that looks like this as a base form of fields to ship to the server: The HTML for this form looks something like this: <div id="divMessage" class="errordisplay" style="display: none"> </div> <div> <div class="label">Name:</div> <div><asp:TextBox runat="server" ID="txtName" /></div> </div> <div> <div class="label">Company:</div> <div><asp:TextBox runat="server" ID="txtCompany"/></div> </div> <div> <div class="label" ></div> <div> <asp:DropDownList runat="server" ID="lstAttending"> <asp:ListItem Text="Attending" Value="Attending"/> <asp:ListItem Text="Not Attending" Value="NotAttending" /> <asp:ListItem Text="Maybe Attending" Value="MaybeAttending" /> <asp:ListItem Text="Not Sure Yet" Value="NotSureYet" /> </asp:DropDownList> </div> </div> <div> <div class="label">Special Needs:<br /> <small>(check all that apply)</small></div> <div> <asp:ListBox runat="server" ID="lstSpecialNeeds" SelectionMode="Multiple"> <asp:ListItem Text="Vegitarian" Value="Vegitarian" /> <asp:ListItem Text="Vegan" Value="Vegan" /> <asp:ListItem Text="Kosher" Value="Kosher" /> <asp:ListItem Text="Special Access" Value="SpecialAccess" /> <asp:ListItem Text="No Binder" Value="NoBinder" /> </asp:ListBox> </div> </div> <div> <div class="label"></div> <div> <asp:CheckBox ID="chkAdditionalGuests" Text="Additional Guests" runat="server" /> </div> </div> <hr /> <input type="button" id="btnSubmit" value="Send Registration" /> The form includes a few different kinds of form fields including a multi-selection listbox to demonstrate retrieving multiple values. Setting up the Server Side [WebMethod] The [WebMethod] on the server we’re going to call is going to be very simple and just capture the content of these values and echo then back as a formatted HTML string. Obviously this is overly simplistic but it serves to demonstrate the simple point of capturing the POST data on the server in an AJAX callback. public class PageMethodsService : System.Web.Services.WebService { [WebMethod] public string SendRegistration(NameValue[] formVars) { StringBuilder sb = new StringBuilder(); sb.AppendFormat("Thank you {0}, <br/><br/>", HttpUtility.HtmlEncode(formVars.Form("txtName"))); sb.AppendLine("You've entered the following: <hr/>"); foreach (NameValue nv in formVars) { // strip out ASP.NET form vars like _ViewState/_EventValidation if (!nv.name.StartsWith("__")) { if (nv.name.StartsWith("txt") || nv.name.StartsWith("lst") || nv.name.StartsWith("chk")) sb.Append(nv.name.Substring(3)); else sb.Append(nv.name); sb.AppendLine(": " + HttpUtility.HtmlEncode(nv.value) + "<br/>"); } } sb.AppendLine("<hr/>"); string[] needs = formVars.FormMultiple("lstSpecialNeeds"); if (needs == null) sb.AppendLine("No Special Needs"); else { sb.AppendLine("Special Needs: <br/>"); foreach (string need in needs) { sb.AppendLine("&nbsp;&nbsp;" + need + "<br/>"); } } return sb.ToString(); } } The key feature of this method is that it receives a custom type called NameValue[] which is an array of NameValue objects that map the structure that the jQuery .serializeArray() function generates. There are two custom types involved in this: The actual NameValue type and a NameValueExtensions class that defines a couple of extension methods for the NameValue[] array type to allow for single (.Form()) and multiple (.FormMultiple()) value retrieval by name. The NameValue class is as simple as this and simply maps the structure of the array elements of .serializeArray(): public class NameValue { public string name { get; set; } public string value { get; set; } } The extension method class defines the .Form() and .FormMultiple() methods to allow easy retrieval of form variables from the returned array: /// <summary> /// Simple NameValue class that maps name and value /// properties that can be used with jQuery's /// $.serializeArray() function and JSON requests /// </summary> public static class NameValueExtensionMethods { /// <summary> /// Retrieves a single form variable from the list of /// form variables stored /// </summary> /// <param name="formVars"></param> /// <param name="name">formvar to retrieve</param> /// <returns>value or string.Empty if not found</returns> public static string Form(this NameValue[] formVars, string name) { var matches = formVars.Where(nv => nv.name.ToLower() == name.ToLower()).FirstOrDefault(); if (matches != null) return matches.value; return string.Empty; } /// <summary> /// Retrieves multiple selection form variables from the list of /// form variables stored. /// </summary> /// <param name="formVars"></param> /// <param name="name">The name of the form var to retrieve</param> /// <returns>values as string[] or null if no match is found</returns> public static string[] FormMultiple(this NameValue[] formVars, string name) { var matches = formVars.Where(nv => nv.name.ToLower() == name.ToLower()).Select(nv => nv.value).ToArray(); if (matches.Length == 0) return null; return matches; } } Using these extension methods it’s easy to retrieve individual values from the array: string name = formVars.Form("txtName"); or multiple values: string[] needs = formVars.FormMultiple("lstSpecialNeeds"); if (needs != null) { // do something with matches } Using these functions in the SendRegistration method it’s easy to retrieve a few form variables directly (txtName and the multiple selections of lstSpecialNeeds) or to iterate over the whole list of values. Of course this is an overly simple example – in typical app you’d probably want to validate the input data and save it to the database and then return some sort of confirmation or possibly an updated data list back to the client. Since this is a full AJAX service callback realize that you don’t have to return simple string values – you can return any of the supported result types (which are most serializable types) including complex hierarchical objects and arrays that make sense to your client code. POSTing Form Variables from the Client to the AJAX Service To call the AJAX service method on the client is straight forward and requires only use of little native jQuery plus JSON serialization functionality. To start add jQuery and the json2.js library to your page: <script src="Scripts/jquery.min.js" type="text/javascript"></script> <script src="Scripts/json2.js" type="text/javascript"></script> json2.js can be found here (be sure to remove the first line from the file): http://www.json.org/json2.js It’s required to handle JSON serialization for those browsers that don’t support it natively. With those script references in the document let’s hookup the button click handler and call the service: $(document).ready(function () { $("#btnSubmit").click(sendRegistration); }); function sendRegistration() { var arForm = $("#form1").serializeArray(); $.ajax({ url: "PageMethodsService.asmx/SendRegistration", type: "POST", contentType: "application/json", data: JSON.stringify({ formVars: arForm }), dataType: "json", success: function (result) { var jEl = $("#divMessage"); jEl.html(result.d).fadeIn(1000); setTimeout(function () { jEl.fadeOut(1000) }, 5000); }, error: function (xhr, status) { alert("An error occurred: " + status); } }); } The key feature in this code is the $("#form1").serializeArray();  call which serializes all the form fields of form1 into an array. Each form var is represented as an object with a name/value property. This array is then serialized into JSON with: JSON.stringify({ formVars: arForm }) The format for the parameter list in AJAX service calls is an object with one property for each parameter of the method. In this case its a single parameter called formVars and we’re assigning the array of form variables to it. The URL to call on the server is the name of the Service (or ASPX Page for Page Methods) plus the name of the method to call. On return the success callback receives the result from the AJAX callback which in this case is the formatted string which is simply assigned to an element in the form and displayed. Remember the result type is whatever the method returns – it doesn’t have to be a string. Note that ASP.NET AJAX and WCF REST return JSON data as a wrapped object so the result has a ‘d’ property that holds the actual response: jEl.html(result.d).fadeIn(1000); Slightly simpler: Using ServiceProxy.js If you want things slightly cleaner you can use the ServiceProxy.js class I’ve mentioned here before. The ServiceProxy class handles a few things for calling ASP.NET and WCF services more cleanly: Automatic JSON encoding Automatic fix up of ‘d’ wrapper property Automatic Date conversion on the client Simplified error handling Reusable and abstracted To add the service proxy add: <script src="Scripts/ServiceProxy.js" type="text/javascript"></script> and then change the code to this slightly simpler version: <script type="text/javascript"> proxy = new ServiceProxy("PageMethodsService.asmx/"); $(document).ready(function () { $("#btnSubmit").click(sendRegistration); }); function sendRegistration() { var arForm = $("#form1").serializeArray(); proxy.invoke("SendRegistration", { formVars: arForm }, function (result) { var jEl = $("#divMessage"); jEl.html(result).fadeIn(1000); setTimeout(function () { jEl.fadeOut(1000) }, 5000); }, function (error) { alert(error.message); } ); } The code is not very different but it makes the call as simple as specifying the method to call, the parameters to pass and the actions to take on success and error. No more remembering which content type and data types to use and manually serializing to JSON. This code also removes the “d” property processing in the response and provides more consistent error handling in that the call always returns an error object regardless of a server error or a communication error unlike the native $.ajax() call. Either approach works and both are pretty easy. The ServiceProxy really pays off if you use lots of service calls and especially if you need to deal with date values returned from the server  on the client. Summary Making Web Service calls and getting POST data to the server is not always the best option – ASP.NET and WCF AJAX services are meant to work with data in objects. However, in some situations it’s simply easier to POST all the captured form data to the server instead of mapping all properties from the input fields to some sort of message object first. For this approach the above POST mechanism is useful as it puts the parsing of the data on the server and leaves the client code lean and mean. It’s even easy to build a custom model binder on the server that can map the array values to properties on an object generically with some relatively simple Reflection code and without having to manually map form vars to properties and do string conversions. Keep in mind though that other approaches also abound. ASP.NET MVC makes it pretty easy to create custom routes to data and the built in model binder makes it very easy to deal with inbound form POST data in its original urlencoded format. The West Wind West Wind Web Toolkit also includes functionality for AJAX callbacks using plain POST values. All that’s needed is a Method parameter to query/form value to specify the method to be called on the server. After that the content type is completely optional and up to the consumer. It’d be nice if the ASP.NET AJAX Service and WCF AJAX Services weren’t so tightly bound to the content type so that you could more easily create open access service endpoints that can take advantage of urlencoded data that is everywhere in existing pages. It would make it much easier to create basic REST endpoints without complicated service configuration. Ah one can dream! In the meantime I hope this article has given you some ideas on how you can transfer POST data from the client to the server using JSON – it might be useful in other scenarios beyond ASP.NET AJAX services as well. Additional Resources ServiceProxy.js A small JavaScript library that wraps $.ajax() to call ASP.NET AJAX and WCF AJAX Services. Includes date parsing extensions to the JSON object, a global dataFilter for processing dates on all jQuery JSON requests, provides cleanup for the .NET wrapped message format and handles errors in a consistent fashion. Making jQuery Calls to WCF/ASMX with a ServiceProxy Client More information on calling ASMX and WCF AJAX services with jQuery and some more background on ServiceProxy.js. Note the implementation has slightly changed since the article was written. ww.jquery.js The West Wind West Wind Web Toolkit also includes ServiceProxy.js in the West Wind jQuery extension library. This version is slightly different and includes embedded json encoding/decoding based on json2.js.© Rick Strahl, West Wind Technologies, 2005-2010Posted in jQuery  ASP.NET  AJAX  

    Read the article

  • Dependency Property WPF Grid

    - by developer
    Hi All, I want to Bind the textblock text in WPF datagrid to a dependency property. Somehow, nothing gets displayed, but when I use the same textblock binding outside the grid, everything works fine. Below is my code, <Window.Resources> <Style x:Key="cellCenterAlign" TargetType="{x:Type toolkit:DataGridCell}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type toolkit:DataGridCell}"> <Grid Background="{TemplateBinding Background}"> <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="ColumnHeaderStyle" TargetType="{x:Type toolkit:DataGridColumnHeader}"> <Setter Property="VerticalContentAlignment" Value="Center" /> <Setter Property="HorizontalContentAlignment" Value="Center"/> </Style> <ObjectDataProvider MethodName="GetValues" ObjectType="{x:Type sys:Enum}" x:Key="RoleValues"> <ObjectDataProvider.MethodParameters> <x:Type TypeName="domain:SubscriptionRole"/> </ObjectDataProvider.MethodParameters> </ObjectDataProvider> <DataTemplate x:Key="myTemplate"> <StackPanel> <TextBlock Text="{Binding Path=OtherSubs}"/> </StackPanel> </DataTemplate> </Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height="220"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <StackPanel Grid.Row="0"> <toolkit:DataGrid Name="definitionGrid" Margin="0,10,0,0" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" IsReadOnly="False" RowHeight="25" FontWeight="Normal" ItemsSource="{Binding programSubscription}" ColumnHeaderStyle="{DynamicResource ColumnHeaderStyle}" SelectionMode="Single" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Width="450" ScrollViewer.VerticalScrollBarVisibility="Auto" Height="200"> <toolkit:DataGrid.Columns> <toolkit:DataGridTextColumn Header="Program" Width="80" Binding="{Binding Program.JobNum}" CellStyle="{StaticResource cellCenterAlign}" IsReadOnly="True"/> <toolkit:DataGridTemplateColumn Header="Role" Width="80" CellStyle="{StaticResource cellCenterAlign}"> <toolkit:DataGridTemplateColumn.CellTemplate> <DataTemplate> <ComboBox SelectedItem="{Binding Role}" ItemsSource="{Binding Source={StaticResource RoleValues}}" Width="70"> <ComboBox.Style> <Style> <Style.Triggers> <DataTrigger Binding="{Binding Path=Role}" Value="Owner"> <Setter Property="ComboBox.Focusable" Value="False"/> <Setter Property="ComboBox.IsEnabled" Value="False"/> <Setter Property="ComboBox.IsHitTestVisible" Value="False"/> </DataTrigger> </Style.Triggers> </Style> </ComboBox.Style> </ComboBox> </DataTemplate> </toolkit:DataGridTemplateColumn.CellTemplate> </toolkit:DataGridTemplateColumn> <toolkit:DataGridCheckBoxColumn Header="Email" Width="60" Binding="{Binding ReceivesEmail}" CellStyle="{StaticResource cellCenterAlign}"/> <!--<toolkit:DataGridTextColumn Header="Others" Width="220" Binding="{Binding programSubscription1.Subscriber.Username}" CellStyle="{StaticResource cellCenterAlign}" IsReadOnly="True"/>--> <toolkit:DataGridTemplateColumn Header="Others" Width="220" CellStyle="{StaticResource cellCenterAlign}" IsReadOnly="True"> <toolkit:DataGridTemplateColumn.CellTemplate> <DataTemplate> <TextBlock Text="{Binding Path=OtherSubs}"/> </DataTemplate> </toolkit:DataGridTemplateColumn.CellTemplate> </toolkit:DataGridTemplateColumn> </toolkit:DataGrid.Columns> </toolkit:DataGrid> <TextBlock Text="{Binding Path=OtherSubs}"/> </StackPanel> <Grid Grid.Row="1"> <Grid.ColumnDefinitions> <ColumnDefinition Width="200"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <StackPanel Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center"> <CheckBox Content="Show Only Active Programs" IsChecked="True" Margin="0,0,8,0"/> </StackPanel> <StackPanel Orientation="Horizontal" VerticalAlignment="Center" Grid.Column="1" HorizontalAlignment="Right"> <Button Content="Save" Height="23" Width="75" Margin="0,0,8,0" Click="Save_Click"/> <Button Content="Cancel" Height="23" Width="75" Margin="0,0,8,0" Click="Cancel_Click" /> </StackPanel> </Grid> </Grid> Code-Behind public partial class ProgramSubscriptions : Window { public static ObservableCollection programSubscription { get; set; } public string OtherSubs { get { return (string)GetValue(OtherSubsProperty); } set { SetValue(OtherSubsProperty, value); } } public static readonly DependencyProperty OtherSubsProperty = DependencyProperty.Register("OtherSubs", typeof(string), typeof(ProgramSubscriptions), new UIPropertyMetadata(string.Empty)); private string CurrentUsername = "test"; public ProgramSubscriptions() { InitializeComponent(); DataContext = this; LoadData(); } protected void LoadData() { programSubscription = new ObservableCollection<ProgramSubscriptionViewModel>(); if (res != null && res.TotalResults > 0) { List<ProgramSubscriptionViewModel> UserPrgList = new List<ProgramSubscriptionViewModel>(); //other.... List<ProgramSubscriptionViewModel> OtherPrgList = new List<ProgramSubscriptionViewModel>(); ArrayList myList = new ArrayList(); foreach (DomainObject obj in res.ResultSet) { ProgramSubscription prg = (ProgramSubscription)obj; if (prg.Subscriber.Username == CurrentUsername) { UserPrgList.Add(new ProgramSubscriptionViewModel(prg)); myList.Add(prg.Program.ID); } else OtherPrgList.Add(new ProgramSubscriptionViewModel(prg)); } for (int i = 0; i < UserPrgList.Count; i++) { ProgramSubscriptionViewModel item = UserPrgList[i]; programSubscription.Add(item); } //other.... for (int i = 0; i < OtherPrgList.Count; i++) { foreach (int y in myList) { ProgramSubscriptionViewModel otheritem = OtherPrgList[i]; if (y == otheritem.Program.ID) OtherSubs += otheritem.Subscriber.Username + ", "; } } } } } I posted the entire code. What exactly I want to do is in the datagridtemplatecolumn for others I want to display the usernames that are not in CurrentUsername, but they have the same program Id as the CurrentUsername. Please do let me know if there is another way that i can make this work, instead of using a dependencyproperty, althouht for testing I did put a textblock below datagrid, and it works perfectly fine.. Help!

    Read the article

  • Metro: Creating an IndexedDbDataSource for WinJS

    - by Stephen.Walther
    The goal of this blog entry is to describe how you can create custom data sources which you can use with the controls in the WinJS library. In particular, I explain how you can create an IndexedDbDataSource which you can use to store and retrieve data from an IndexedDB database. If you want to skip ahead, and ignore all of the fascinating content in-between, I’ve included the complete code for the IndexedDbDataSource at the very bottom of this blog entry. What is IndexedDB? IndexedDB is a database in the browser. You can use the IndexedDB API with all modern browsers including Firefox, Chrome, and Internet Explorer 10. And, of course, you can use IndexedDB with Metro style apps written with JavaScript. If you need to persist data in a Metro style app written with JavaScript then IndexedDB is a good option. Each Metro app can only interact with its own IndexedDB databases. And, IndexedDB provides you with transactions, indices, and cursors – the elements of any modern database. An IndexedDB database might be different than the type of database that you normally use. An IndexedDB database is an object-oriented database and not a relational database. Instead of storing data in tables, you store data in object stores. You store JavaScript objects in an IndexedDB object store. You create new IndexedDB object stores by handling the upgradeneeded event when you attempt to open a connection to an IndexedDB database. For example, here’s how you would both open a connection to an existing database named TasksDB and create the TasksDB database when it does not already exist: var reqOpen = window.indexedDB.open(“TasksDB”, 2); reqOpen.onupgradeneeded = function (evt) { var newDB = evt.target.result; newDB.createObjectStore("tasks", { keyPath: "id", autoIncrement: true }); }; reqOpen.onsuccess = function () { var db = reqOpen.result; // Do something with db }; When you call window.indexedDB.open(), and the database does not already exist, then the upgradeneeded event is raised. In the code above, the upgradeneeded handler creates a new object store named tasks. The new object store has an auto-increment column named id which acts as the primary key column. If the database already exists with the right version, and you call window.indexedDB.open(), then the success event is raised. At that point, you have an open connection to the existing database and you can start doing something with the database. You use asynchronous methods to interact with an IndexedDB database. For example, the following code illustrates how you would add a new object to the tasks object store: var transaction = db.transaction(“tasks”, “readwrite”); var reqAdd = transaction.objectStore(“tasks”).add({ name: “Feed the dog” }); reqAdd.onsuccess = function() { // Tasks added successfully }; The code above creates a new database transaction, adds a new task to the tasks object store, and handles the success event. If the new task gets added successfully then the success event is raised. Creating a WinJS IndexedDbDataSource The most powerful control in the WinJS library is the ListView control. This is the control that you use to display a collection of items. If you want to display data with a ListView control, you need to bind the control to a data source. The WinJS library includes two objects which you can use as a data source: the List object and the StorageDataSource object. The List object enables you to represent a JavaScript array as a data source and the StorageDataSource enables you to represent the file system as a data source. If you want to bind an IndexedDB database to a ListView then you have a choice. You can either dump the items from the IndexedDB database into a List object or you can create a custom data source. I explored the first approach in a previous blog entry. In this blog entry, I explain how you can create a custom IndexedDB data source. Implementing the IListDataSource Interface You create a custom data source by implementing the IListDataSource interface. This interface contains the contract for the methods which the ListView needs to interact with a data source. The easiest way to implement the IListDataSource interface is to derive a new object from the base VirtualizedDataSource object. The VirtualizedDataSource object requires a data adapter which implements the IListDataAdapter interface. Yes, because of the number of objects involved, this is a little confusing. Your code ends up looking something like this: var IndexedDbDataSource = WinJS.Class.derive( WinJS.UI.VirtualizedDataSource, function (dbName, dbVersion, objectStoreName, upgrade, error) { this._adapter = new IndexedDbDataAdapter(dbName, dbVersion, objectStoreName, upgrade, error); this._baseDataSourceConstructor(this._adapter); }, { nuke: function () { this._adapter.nuke(); }, remove: function (key) { this._adapter.removeInternal(key); } } ); The code above is used to create a new class named IndexedDbDataSource which derives from the base VirtualizedDataSource class. In the constructor for the new class, the base class _baseDataSourceConstructor() method is called. A data adapter is passed to the _baseDataSourceConstructor() method. The code above creates a new method exposed by the IndexedDbDataSource named nuke(). The nuke() method deletes all of the objects from an object store. The code above also overrides a method named remove(). Our derived remove() method accepts any type of key and removes the matching item from the object store. Almost all of the work of creating a custom data source goes into building the data adapter class. The data adapter class implements the IListDataAdapter interface which contains the following methods: · change() · getCount() · insertAfter() · insertAtEnd() · insertAtStart() · insertBefore() · itemsFromDescription() · itemsFromEnd() · itemsFromIndex() · itemsFromKey() · itemsFromStart() · itemSignature() · moveAfter() · moveBefore() · moveToEnd() · moveToStart() · remove() · setNotificationHandler() · compareByIdentity Fortunately, you are not required to implement all of these methods. You only need to implement the methods that you actually need. In the case of the IndexedDbDataSource, I implemented the getCount(), itemsFromIndex(), insertAtEnd(), and remove() methods. If you are creating a read-only data source then you really only need to implement the getCount() and itemsFromIndex() methods. Implementing the getCount() Method The getCount() method returns the total number of items from the data source. So, if you are storing 10,000 items in an object store then this method would return the value 10,000. Here’s how I implemented the getCount() method: getCount: function () { var that = this; return new WinJS.Promise(function (complete, error) { that._getObjectStore().then(function (store) { var reqCount = store.count(); reqCount.onerror = that._error; reqCount.onsuccess = function (evt) { complete(evt.target.result); }; }); }); } The first thing that you should notice is that the getCount() method returns a WinJS promise. This is a requirement. The getCount() method is asynchronous which is a good thing because all of the IndexedDB methods (at least the methods implemented in current browsers) are also asynchronous. The code above retrieves an object store and then uses the IndexedDB count() method to get a count of the items in the object store. The value is returned from the promise by calling complete(). Implementing the itemsFromIndex method When a ListView displays its items, it calls the itemsFromIndex() method. By default, it calls this method multiple times to get different ranges of items. Three parameters are passed to the itemsFromIndex() method: the requestIndex, countBefore, and countAfter parameters. The requestIndex indicates the index of the item from the database to show. The countBefore and countAfter parameters represent hints. These are integer values which represent the number of items before and after the requestIndex to retrieve. Again, these are only hints and you can return as many items before and after the request index as you please. Here’s how I implemented the itemsFromIndex method: itemsFromIndex: function (requestIndex, countBefore, countAfter) { var that = this; return new WinJS.Promise(function (complete, error) { that.getCount().then(function (count) { if (requestIndex >= count) { return WinJS.Promise.wrapError(new WinJS.ErrorFromName(WinJS.UI.FetchError.doesNotExist)); } var startIndex = Math.max(0, requestIndex - countBefore); var endIndex = Math.min(count, requestIndex + countAfter + 1); that._getObjectStore().then(function (store) { var index = 0; var items = []; var req = store.openCursor(); req.onerror = that._error; req.onsuccess = function (evt) { var cursor = evt.target.result; if (index < startIndex) { index = startIndex; cursor.advance(startIndex); return; } if (cursor && index < endIndex) { index++; items.push({ key: cursor.value[store.keyPath].toString(), data: cursor.value }); cursor.continue(); return; } results = { items: items, offset: requestIndex - startIndex, totalCount: count }; complete(results); }; }); }); }); } In the code above, a cursor is used to iterate through the objects in an object store. You fetch the next item in the cursor by calling either the cursor.continue() or cursor.advance() method. The continue() method moves forward by one object and the advance() method moves forward a specified number of objects. Each time you call continue() or advance(), the success event is raised again. If the cursor is null then you know that you have reached the end of the cursor and you can return the results. Some things to be careful about here. First, the return value from the itemsFromIndex() method must implement the IFetchResult interface. In particular, you must return an object which has an items, offset, and totalCount property. Second, each item in the items array must implement the IListItem interface. Each item should have a key and a data property. Implementing the insertAtEnd() Method When creating the IndexedDbDataSource, I wanted to go beyond creating a simple read-only data source and support inserting and deleting objects. If you want to support adding new items with your data source then you need to implement the insertAtEnd() method. Here’s how I implemented the insertAtEnd() method for the IndexedDbDataSource: insertAtEnd:function(unused, data) { var that = this; return new WinJS.Promise(function (complete, error) { that._getObjectStore("readwrite").done(function(store) { var reqAdd = store.add(data); reqAdd.onerror = that._error; reqAdd.onsuccess = function (evt) { var reqGet = store.get(evt.target.result); reqGet.onerror = that._error; reqGet.onsuccess = function (evt) { var newItem = { key:evt.target.result[store.keyPath].toString(), data:evt.target.result } complete(newItem); }; }; }); }); } When implementing the insertAtEnd() method, you need to be careful to return an object which implements the IItem interface. In particular, you should return an object that has a key and a data property. The key must be a string and it uniquely represents the new item added to the data source. The value of the data property represents the new item itself. Implementing the remove() Method Finally, you use the remove() method to remove an item from the data source. You call the remove() method with the key of the item which you want to remove. Implementing the remove() method in the case of the IndexedDbDataSource was a little tricky. The problem is that an IndexedDB object store uses an integer key and the VirtualizedDataSource requires a string key. For that reason, I needed to override the remove() method in the derived IndexedDbDataSource class like this: var IndexedDbDataSource = WinJS.Class.derive( WinJS.UI.VirtualizedDataSource, function (dbName, dbVersion, objectStoreName, upgrade, error) { this._adapter = new IndexedDbDataAdapter(dbName, dbVersion, objectStoreName, upgrade, error); this._baseDataSourceConstructor(this._adapter); }, { nuke: function () { this._adapter.nuke(); }, remove: function (key) { this._adapter.removeInternal(key); } } ); When you call remove(), you end up calling a method of the IndexedDbDataAdapter named removeInternal() . Here’s what the removeInternal() method looks like: setNotificationHandler: function (notificationHandler) { this._notificationHandler = notificationHandler; }, removeInternal: function(key) { var that = this; return new WinJS.Promise(function (complete, error) { that._getObjectStore("readwrite").done(function (store) { var reqDelete = store.delete (key); reqDelete.onerror = that._error; reqDelete.onsuccess = function (evt) { that._notificationHandler.removed(key.toString()); complete(); }; }); }); } The removeInternal() method calls the IndexedDB delete() method to delete an item from the object store. If the item is deleted successfully then the _notificationHandler.remove() method is called. Because we are not implementing the standard IListDataAdapter remove() method, we need to notify the data source (and the ListView control bound to the data source) that an item has been removed. The way that you notify the data source is by calling the _notificationHandler.remove() method. Notice that we get the _notificationHandler in the code above by implementing another method in the IListDataAdapter interface: the setNotificationHandler() method. You can raise the following types of notifications using the _notificationHandler: · beginNotifications() · changed() · endNotifications() · inserted() · invalidateAll() · moved() · removed() · reload() These methods are all part of the IListDataNotificationHandler interface in the WinJS library. Implementing the nuke() Method I wanted to implement a method which would remove all of the items from an object store. Therefore, I created a method named nuke() which calls the IndexedDB clear() method: nuke: function () { var that = this; return new WinJS.Promise(function (complete, error) { that._getObjectStore("readwrite").done(function (store) { var reqClear = store.clear(); reqClear.onerror = that._error; reqClear.onsuccess = function (evt) { that._notificationHandler.reload(); complete(); }; }); }); } Notice that the nuke() method calls the _notificationHandler.reload() method to notify the ListView to reload all of the items from its data source. Because we are implementing a custom method here, we need to use the _notificationHandler to send an update. Using the IndexedDbDataSource To illustrate how you can use the IndexedDbDataSource, I created a simple task list app. You can add new tasks, delete existing tasks, and nuke all of the tasks. You delete an item by selecting an item (swipe or right-click) and clicking the Delete button. Here’s the HTML page which contains the ListView, the form for adding new tasks, and the buttons for deleting and nuking tasks: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>DataSources</title> <!-- WinJS references --> <link href="//Microsoft.WinJS.1.0.RC/css/ui-dark.css" rel="stylesheet" /> <script src="//Microsoft.WinJS.1.0.RC/js/base.js"></script> <script src="//Microsoft.WinJS.1.0.RC/js/ui.js"></script> <!-- DataSources references --> <link href="indexedDb.css" rel="stylesheet" /> <script type="text/javascript" src="indexedDbDataSource.js"></script> <script src="indexedDb.js"></script> </head> <body> <div id="tmplTask" data-win-control="WinJS.Binding.Template"> <div class="taskItem"> Id: <span data-win-bind="innerText:id"></span> <br /><br /> Name: <span data-win-bind="innerText:name"></span> </div> </div> <div id="lvTasks" data-win-control="WinJS.UI.ListView" data-win-options="{ itemTemplate: select('#tmplTask'), selectionMode: 'single' }"></div> <form id="frmAdd"> <fieldset> <legend>Add Task</legend> <label>New Task</label> <input id="inputTaskName" required /> <button>Add</button> </fieldset> </form> <button id="btnNuke">Nuke</button> <button id="btnDelete">Delete</button> </body> </html> And here is the JavaScript code for the TaskList app: /// <reference path="//Microsoft.WinJS.1.0.RC/js/base.js" /> /// <reference path="//Microsoft.WinJS.1.0.RC/js/ui.js" /> function init() { WinJS.UI.processAll().done(function () { var lvTasks = document.getElementById("lvTasks").winControl; // Bind the ListView to its data source var tasksDataSource = new DataSources.IndexedDbDataSource("TasksDB", 1, "tasks", upgrade); lvTasks.itemDataSource = tasksDataSource; // Wire-up Add, Delete, Nuke buttons document.getElementById("frmAdd").addEventListener("submit", function (evt) { evt.preventDefault(); tasksDataSource.beginEdits(); tasksDataSource.insertAtEnd(null, { name: document.getElementById("inputTaskName").value }).done(function (newItem) { tasksDataSource.endEdits(); document.getElementById("frmAdd").reset(); lvTasks.ensureVisible(newItem.index); }); }); document.getElementById("btnDelete").addEventListener("click", function () { if (lvTasks.selection.count() == 1) { lvTasks.selection.getItems().done(function (items) { tasksDataSource.remove(items[0].data.id); }); } }); document.getElementById("btnNuke").addEventListener("click", function () { tasksDataSource.nuke(); }); // This method is called to initialize the IndexedDb database function upgrade(evt) { var newDB = evt.target.result; newDB.createObjectStore("tasks", { keyPath: "id", autoIncrement: true }); } }); } document.addEventListener("DOMContentLoaded", init); The IndexedDbDataSource is created and bound to the ListView control with the following two lines of code: var tasksDataSource = new DataSources.IndexedDbDataSource("TasksDB", 1, "tasks", upgrade); lvTasks.itemDataSource = tasksDataSource; The IndexedDbDataSource is created with four parameters: the name of the database to create, the version of the database to create, the name of the object store to create, and a function which contains code to initialize the new database. The upgrade function creates a new object store named tasks with an auto-increment property named id: function upgrade(evt) { var newDB = evt.target.result; newDB.createObjectStore("tasks", { keyPath: "id", autoIncrement: true }); } The Complete Code for the IndexedDbDataSource Here’s the complete code for the IndexedDbDataSource: (function () { /************************************************ * The IndexedDBDataAdapter enables you to work * with a HTML5 IndexedDB database. *************************************************/ var IndexedDbDataAdapter = WinJS.Class.define( function (dbName, dbVersion, objectStoreName, upgrade, error) { this._dbName = dbName; // database name this._dbVersion = dbVersion; // database version this._objectStoreName = objectStoreName; // object store name this._upgrade = upgrade; // database upgrade script this._error = error || function (evt) { console.log(evt.message); }; }, { /******************************************* * IListDataAdapter Interface Methods ********************************************/ getCount: function () { var that = this; return new WinJS.Promise(function (complete, error) { that._getObjectStore().then(function (store) { var reqCount = store.count(); reqCount.onerror = that._error; reqCount.onsuccess = function (evt) { complete(evt.target.result); }; }); }); }, itemsFromIndex: function (requestIndex, countBefore, countAfter) { var that = this; return new WinJS.Promise(function (complete, error) { that.getCount().then(function (count) { if (requestIndex >= count) { return WinJS.Promise.wrapError(new WinJS.ErrorFromName(WinJS.UI.FetchError.doesNotExist)); } var startIndex = Math.max(0, requestIndex - countBefore); var endIndex = Math.min(count, requestIndex + countAfter + 1); that._getObjectStore().then(function (store) { var index = 0; var items = []; var req = store.openCursor(); req.onerror = that._error; req.onsuccess = function (evt) { var cursor = evt.target.result; if (index < startIndex) { index = startIndex; cursor.advance(startIndex); return; } if (cursor && index < endIndex) { index++; items.push({ key: cursor.value[store.keyPath].toString(), data: cursor.value }); cursor.continue(); return; } results = { items: items, offset: requestIndex - startIndex, totalCount: count }; complete(results); }; }); }); }); }, insertAtEnd:function(unused, data) { var that = this; return new WinJS.Promise(function (complete, error) { that._getObjectStore("readwrite").done(function(store) { var reqAdd = store.add(data); reqAdd.onerror = that._error; reqAdd.onsuccess = function (evt) { var reqGet = store.get(evt.target.result); reqGet.onerror = that._error; reqGet.onsuccess = function (evt) { var newItem = { key:evt.target.result[store.keyPath].toString(), data:evt.target.result } complete(newItem); }; }; }); }); }, setNotificationHandler: function (notificationHandler) { this._notificationHandler = notificationHandler; }, /***************************************** * IndexedDbDataSource Method ******************************************/ removeInternal: function(key) { var that = this; return new WinJS.Promise(function (complete, error) { that._getObjectStore("readwrite").done(function (store) { var reqDelete = store.delete (key); reqDelete.onerror = that._error; reqDelete.onsuccess = function (evt) { that._notificationHandler.removed(key.toString()); complete(); }; }); }); }, nuke: function () { var that = this; return new WinJS.Promise(function (complete, error) { that._getObjectStore("readwrite").done(function (store) { var reqClear = store.clear(); reqClear.onerror = that._error; reqClear.onsuccess = function (evt) { that._notificationHandler.reload(); complete(); }; }); }); }, /******************************************* * Private Methods ********************************************/ _ensureDbOpen: function () { var that = this; // Try to get cached Db if (that._cachedDb) { return WinJS.Promise.wrap(that._cachedDb); } // Otherwise, open the database return new WinJS.Promise(function (complete, error, progress) { var reqOpen = window.indexedDB.open(that._dbName, that._dbVersion); reqOpen.onerror = function (evt) { error(); }; reqOpen.onupgradeneeded = function (evt) { that._upgrade(evt); that._notificationHandler.invalidateAll(); }; reqOpen.onsuccess = function () { that._cachedDb = reqOpen.result; complete(that._cachedDb); }; }); }, _getObjectStore: function (type) { type = type || "readonly"; var that = this; return new WinJS.Promise(function (complete, error) { that._ensureDbOpen().then(function (db) { var transaction = db.transaction(that._objectStoreName, type); complete(transaction.objectStore(that._objectStoreName)); }); }); }, _get: function (key) { return new WinJS.Promise(function (complete, error) { that._getObjectStore().done(function (store) { var reqGet = store.get(key); reqGet.onerror = that._error; reqGet.onsuccess = function (item) { complete(item); }; }); }); } } ); var IndexedDbDataSource = WinJS.Class.derive( WinJS.UI.VirtualizedDataSource, function (dbName, dbVersion, objectStoreName, upgrade, error) { this._adapter = new IndexedDbDataAdapter(dbName, dbVersion, objectStoreName, upgrade, error); this._baseDataSourceConstructor(this._adapter); }, { nuke: function () { this._adapter.nuke(); }, remove: function (key) { this._adapter.removeInternal(key); } } ); WinJS.Namespace.define("DataSources", { IndexedDbDataSource: IndexedDbDataSource }); })(); Summary In this blog post, I provided an overview of how you can create a new data source which you can use with the WinJS library. I described how you can create an IndexedDbDataSource which you can use to bind a ListView control to an IndexedDB database. While describing how you can create a custom data source, I explained how you can implement the IListDataAdapter interface. You also learned how to raise notifications — such as a removed or invalidateAll notification — by taking advantage of the methods of the IListDataNotificationHandler interface.

    Read the article

< Previous Page | 1 2 3