WPF ListView with buttons on each line - c#

I have a list of Games which just has an ID, a Date, and a Time.
I am setting this list as the DataContext.
I then have a DataTemplate for these games that is:
<DataTemplate DataType="{x:Type loc:Game}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Name="dateBlock" Grid.Column="0" Grid.Row="1"
Text="{Binding Date, StringFormat=d}"></TextBlock>
<TextBlock Name="TimeBlock" Grid.Column="1" Grid.Row="1"
Text="{Binding Time}"></TextBlock>
//need to but a button here for each row
</Grid>
</DataTemplate>
To use the template, I am simply just doing this:
<ListBox ItemsSource="{Binding}"></ListBox>
I need to add a Button to each line in this list view that have the same click event, but will somehow pass the ID of the game for which button is being clicked.
How can I do this? I am stuck.
If it doesn't make sense let me know and I will try to explain better.

For the first part, add a Button to the DataTemplate and subscribe to the Click event
<DataTemplate DataType="{x:Type loc:Game}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Name="dateBlock" Grid.Column="0" Grid.Row="1" Text="{Binding Date, StringFormat=d}"></TextBlock>
<TextBlock Name="TimeBlock" Grid.Column="1" Grid.Row="1" Text="{Binding Time}"></TextBlock>
<Button Click="Button_Click">X</Button>
</Grid>
</DataTemplate>
In the code behind event handler, you can get the DataContext of the clicked Button and find out the Id like
private void Button_Click(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
Game game = button.DataContext as Game;
int id = game.ID;
// ...
}

Easily. Add a Button to your DataTemplate, give it a Command and then set the CommandParameter="{Binding}". The DataContext within a DataTemplate is the object.
As requested, some links to using commands.
WPF Commands Part 1: Basics
WPF Commands Part 2: Command Bindings and Gestures
MSDN Understanding Routed Events and Commands In WPF (ADVANCED)
HTH,

With a ListBox.ItemTemplate. Then in your click event you can get the object via DataContext.
<ListBox.ItemTemplate>
<DataTemplate>
<Button Content="^" IsEnabled="{Binding Path=IsNotFirst, Mode=OneWay}"
Click="btnMoveFDAup"/>
</DataTemplate>
</ListBox.ItemTemplate>
private void btnMoveFDAup(object sender, RoutedEventArgs e)
{
Button btn = ((Button)sender);
// btn.DataContext will get you to the row object where you can retrieve the ID
}

Related

Two AutoCompleteBox controls in two different tabs in wpf

I have used two AutoCompleteBox controls in two different tabs in a wpf window.
Control in first tab is working fine. First Control
But the control in second tab, data is binding and I could see the matched strings in the dropdown list.
I couldn't select the items from the list using mouse or arrow keys. Second Control
When I moved the second control to new window, it is working fine.
I couldn't understand what is the actual issue?
Please find below code:
Autocompletebox in first tab
<ctrls:AutoCompleteBox Grid.Column="1" x:Name="txtFirst" VerticalAlignment="Center" Margin="0,0,0,10" />
Autocompletebox in Second tab
<ctrls:AutoCompleteBox Grid.Column="1" x:Name="txtSecond" VerticalAlignment="Center" Margin="0,0,0,10" />
Xaml code for Tab control
<TabControl Grid.Row="1"
x:Name="tabCtrl"
SelectionChanged="tabCtrl_SelectionChanged">
<TabItem x:Name="tab1"
Header="First">
<ScrollViewer>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="500" />
</Grid.ColumnDefinitions>
<TextBlock Text="First"
VerticalAlignment="Center"
Margin="0,0,0,10" />
<ctrls:AutoCompleteBox Grid.Column="1"
x:Name="txtFirst"
VerticalAlignment="Center"
Margin="0,0,0,10" />
</Grid>
</ScrollViewer>
</TabItem>
<TabItem x:Name="tab2"
Header="Second">
<ScrollViewer>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="500" />
</Grid.ColumnDefinitions>
<TextBlock Text="Second"
VerticalAlignment="Center"
Margin="0,0,0,10" />
<ctrls:AutoCompleteBox Grid.Column="1"
x:Name="txtSecond"
VerticalAlignment="Center"
Margin="0,0,0,10" />
</Grid>
</ScrollViewer>
</TabItem>
</TabControl>
And the code behind
var data = db.tblname.Select(c => c.propertyname).ToList();
txtFirst.ItemsSource = data;
var data1 = db.tblname.Select(c => c.propertyname).ToList();
txtSecond.ItemsSource = data1;
Your C# code is fine.
You should take a look at the XAML.
(Provide XAML to us as well.)
After thorough debugging of my code, I figured out that the issue was due to SelectionChanged event of TabControl.
Whenever I select an item from the Autocompletebox control, SelectionChanged event of TabControl was getting fired, which led to chaos, as my binding logic for Autocompletebox was in SelectionChanged event.
Still I am not getting why do my Autocompletebox control triggers SelectionChanged event of TabControl without the registeration of SelectionChanged event for Autocompletebox Control.
But Below code overcame the issue
private void tabCtrl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.Source is TabControl)
{
// Business logic for binding autocompletebox
}
}
Thanks everyone for their support!

loop each row item in a listview then evaluate which radiobutton isChecked

I am creating a WPF application that allows the user to take a quiz then submit their answers. I have a ListView which displays 2 Label and 4 RadioButton for each row. The first Label is for the item number. The second Label is the question for the current item. The 4 RadioButton are the choices that the user may select. The items in my ListView are binded from a class that I created which is named "Question". It has 7 properties, namely: number, problem, choice1, choice2, choice3, choice4, and correct_answer. Only the property "correct_answer" is not displayed in the ListView. If I click the Submit Button, I want to know which RadioButton isChecked for each row item in the ListView for me to be able to know if they answered each item correctly and provide them with a score on how many items they got right. Please advise.
Below is my xaml
<ListView x:Name="list_question" ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal">
<Label Content="{Binding number}" HorizontalAlignment="Left" VerticalAlignment="Top"></Label>
<Label Content="{Binding problem}" HorizontalAlignment="Left" HorizontalContentAlignment="Left" VerticalAlignment="Top"></Label>
</StackPanel>
<RadioButton Grid.Row="1" Content="{Binding choice1}"></RadioButton>
<RadioButton Grid.Row="1" Grid.Column="1" Content="{Binding choice3}"></RadioButton>
<RadioButton Grid.Row="2" Content="{Binding choice2}"></RadioButton>
<RadioButton Grid.Row="2" Grid.Column="1" Content="{Binding choice4}"></RadioButton>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
My Button click event handler
private void btn_submit_Click(object sender, RoutedEventArgs e)
{
foreach (var item in list_question.Items)
{
}
}
If you are using radio button to select one choice out of 4 then first of all you need to put same name for all options then will help u to get selected choice as well as allow end user to select only one option.

wpf user control - how to set text from outer uc

i have a problem , i have 2 uc that displayed in main windows.
i want when i press on button in the first uc the text in the other uc will change
this the axml i use and the code
first uc
<Grid.RowDefinitions>
<RowDefinition ></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Width="40" Height="40" Name="playbtn" HorizontalAlignment="Left" Grid.Row="0" Grid.Column="0" Click="playbtn_Click" >
<Button.Content>
<Image Source="/img/player_play.png" ></Image>
</Button.Content>
</Button>
<Button Width="40" Height="40" Name="pausebtn" Grid.Column="1" Grid.Row="0" >
<Button.Content>
<Image Source="/img/player_pause.png" ></Image>
</Button.Content>
</Button>
<Button Width="40" Height="40" Name="stopbtn" Grid.Column="2" Grid.Row="0" >
<Button.Content>
<Image Source="/img/player_stop.png" ></Image>
</Button.Content>
</Button>
</Grid>
</StackPanel>
</Grid>
</StackPanel>
secound uc <TextBlock Name="Progresstimertext" Text="00:00:00" FontSize="20"></TextBlock>
so i want to press on start button and the timer will be change? how to
10x
This should be managed in the View Model of your Main Window, as this seems the only location that has knowledge of both controls and it sounds as though each of your user control's shouldn't necessarily have knowledge of each other.
Ideally, you should have a reference to each of your user controls in the code-behind (or view model class is you have a dedicated one).
If in code behind, you would simply expose these by giving them names.
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="your controls reference here">
<Grid>
<Grid.ColumnDefinitions>
</ColumnDefinition>
</ColumnDefinition>
</Grid.ColumnDefinitions>
<controls:UserControl1 x:Name="Control1"/>
<controls:UserControl2 x:Name="Control2" Grid.Column="1"/>
</Grid>
</Window>
Now you can reference them in your code behind by name Control1 and Control2. These user control classes should be exposing the properties that you want to control, in your case ProgressTimerText, such that, in the code-behind, you can set it easily such as
Control2.ProgressTimerText = "00:00:00";
Where to do this? Well you probably want to create a Stopped event on your Control1, that you can attach to your code behind - in your case, something like Stopped. In your UserControl1 class you should declare something like
public event EventHandler Stopped;
And then in the local event handler for the Click of the stop button, invoke that event.
private void Stop_Click(object sender, RoutedEventArgs e)
{
if (Stopped != null)
Stopped(this, e);
}
Attach that in your MainWindow:
<controls:UserControl1 x:Name="Control1" Stopped=Control1_Stopped/>
Now in your code-behind you should have something like:
private void Control1_Stopped(object sender, RoutedEventArgs e)
{
Control2.ProgressTimerText = "00:00:00";
}

pivot page in windows phone 8 LoadedPivot event not firing?

i just started with generic forms for windows phone 8 development.
No i want to test if a certain pivotitem is selected, then it should fire a function to load a grid into that pivot item.
here is my xaml and my code so far
XAML:
<phone:Pivot Name="mainpivot" Title="MY APPLICATION" LoadingPivotItem="mainpivot_LoadingPivotItem" LoadedPivotItem="mainpivot_LoadedPivotItem_1">
<!--Pivot item one-->
<phone:PivotItem Name="staticpivot" Header="static">
<!--Double line list with text wrapping-->
<Grid Name="staticGrid" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox Name="txtUsername" Grid.Column="1" Height="70"></TextBox>
<TextBox Name="txtPassword" Grid.Row="1" Height="70" Grid.Column="1"></TextBox>
<TextBox Name="txtdescription" Grid.Row="2" Height="150" Grid.Column="1" TextWrapping="Wrap"></TextBox>
<TextBlock Height="40" Text="USERNAME" HorizontalAlignment="Center"></TextBlock>
<TextBlock Height="40" Text="PASSWORD" HorizontalAlignment="Center" Grid.Row="1"></TextBlock>
<TextBlock Height="40" Text="DESCRIPTION" HorizontalAlignment="Center" Grid.Row="2"></TextBlock>
<Button Grid.Row="4" Grid.ColumnSpan="2" Tap="Button_Tap">SAVE DATA</Button>
</Grid>
</phone:PivotItem>
<!--Pivot item two-->
<phone:PivotItem x:Name="genericpivot" Header="generic">
<!--Double line list no text wrapping-->
</phone:PivotItem>
</phone:Pivot>
as you can see the 2nd pivot has nothing in it, i am going to populate it dynamically with controls.
the problem is here in the code :
private void mainpivot_LoadedPivotItem_1(object sender, PivotItemEventArgs e)
{
if (e.Item.Name == "genericpivot")
{
loadDetailForPivot();
}
}
this function does not fire when i debug and put a breakpoint there.
can anyone tell my why? or give a link that explains it.
regards
To clarify, are you trying to populate the selected pivot item once it's selected?
I believe what you are after is picking up a change to the pivot controls selectedindex, such as (VB.net, sorry):
Private Sub PivotItem_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles PivotItem.SelectionChanged
If PivotItem.SelectedIndex = 1 Then LoadDetailForPivot
End Sub
However...why do you not load the controls beforehand? Wouldn't that be quicker (i.e. no delay while things are loaded as the user pivots). I did this on a previous app and the pivoting was jerky as a result.

binding a textbox on gridfrom

I have a datagrid which is populated from a web service. I want to fill a form based on the selected item in the datagrid.
This is what I use to set the DataContext (Which is a grid)
private void PublisherSearchList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
this.PublisherItem.DataContext = (Publisher)PublisherSearchList.SelectedItem;
}
XAML
<Grid Name="PublisherItem" Width="390" Margin="5" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20"></RowDefinition>
</Grid.RowDefinitions>
<TextBox Name="CompanyName" DataContext="{Binding PublisherName}"
Grid.Column="0" Grid.Row="0"></TextBox>
</Grid>
How can this be done?
Have you tried to bind your control with properties?
For example if your Publisher class has property Name than you can bind this way
DataContext="{Binding Publisher, Path=Name}"

Categories

Resources