I have a ListView with one button and one entry on it's ItemTemplate
<ListView
x:Name="LstMedios"
Grid.Row="2"
ItemsSource="{Binding MediosDePago}"
SelectedItem="{Binding MedioPagoSeleccionado,Mode=TwoWay}"
SelectionMode="Single">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid ColumnDefinitions="2*,*" >
<Button
Text="My button"
HeightRequest="40"
HorizontalOptions="FillAndExpand" Margin="5,5" />
<Entry
Text="{Binding NumValor,StringFormat='{0:c}'}"
Keyboard="Numeric"
Grid.Column="1"
HorizontalTextAlignment="End" Margin="0,5,5,5">
</Entry>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I expect when my Entry is focused then my listview SelectedItem must be set, but it remains null.
What is the proper way to force my listview to automatically set SelectedItem when any of its controls on ItemTemplate is focused?
Full sample
To begin with, what you expect is that when directly hitting on the Button or the Entry(get focused), the SelectedItem below should be triggered.
public TestItem SelectedItem
{
get => _SelectedItem;
set => SetProperty(ref _SelectedItem, value);
}
However, the SelectedItem will only be set if clicking on the frame border or outside of it and the background color of the selected item will be Orange. And this potential issue happens both in ListView and CollectionView.
In conclusion, this potential issue is related or similar to CollectionView's SelectionChanged method cannot be triggered when tapping the item directly #9567. You can try this workaround provided by PhoenixWyllow or follow up on it. Besides, you can also raise a new issue on Github if you are willing to.
Update:
For now, Juan implemented a transparent button over the Entry element this way can get access to selected item posting it from CommandParameter.
Related
I'm creating a form and now attempting to get the value for a summary page.
I'm not having trouble in selecting the radio buttons. The problem lies in getting the value of radio button in material-ui for a summary page/print the value.
The following are my code:
Registering Office: <br></br>
<Grid container direction={'row'} spacing={1}>
<Grid item xs={3}>
<Radio id="RegOffice" value="Head Office" checked={RegOffice==="Head Office"} onChange={handleChangeRegOffice}
color="primary"
/>
Head Office
</Grid>
<Grid item xs={3}>
<Radio id="RegOffice" value="Branch Office" checked={RegOffice==="Branch Office"} onChange={handleChangeRegOffice}
color="primary" />
Branch Office
</Grid>
<Grid itemxs={3}>
<Radio id="RegOffice" value="Facility" checked={RegOffice==="Facility"}
onChange={handleChangeRegOffice}
color="primary" //label="Facility"
/>
Facility
</Grid>
</Grid>
for handlechange:
const [RegOffice, setRegOffice] = React.useState('Head Office')
const handleChangeRegOffice = (event) => { setRegOffice(event.target.value)
console.log(RegOffice) }
=end=
With no luck, every time I call "RegOffice", it always returns blank value.
Appreciate any help. thank you
You code is fine, but you're doing console.log(RegOffice), before the state is updated. React set/update state Asynchronously, which means when you're viewing the console.log(RegOffice) the regOffice state still contains the old state value. The updating state is a really vital React concept and learning about it will be very beneficial for creating/understanding the React Code. Here is a docs link
I've created the codesandbox link out of your code and just moved the console.log() outside the handleChangeRegOffice function.
const handleChangeRegOffice = (event) => {
setRegOffice(event.target.value);
};
console.log(RegOffice);
the updated function and console statement
I have an interaction request pop up and inside that pop up, I have few controls like time picker, radcombobox and so on. I want change events of these controls hit in my view model class using prism commands.
my sample code is not working, time picket value change is not hitting on OnReasonTimeChanged Method.
XAML file
<i:Interaction.Triggers>
<i:EventTrigger SourceName=" " EventName="ValueChanged">
<i:InvokeCommandAction Command="{Binding ReasonTimeChanged}" />
</i:EventTrigger>
<prism:InteractionRequestTrigger SourceObject="{Binding SummaryConfirmationInteractionRequest}">
<prism:PopupChildWindowAction>
<prism:PopupChildWindowAction.ContentTemplate>
<DataTemplate>
<StackPanel Width="Auto" ScrollViewer.VerticalScrollBarVisibility="Hidden" Height="Auto"
MaxHeight="400" >
<ScrollViewer BorderThickness="1" VerticalScrollBarVisibility="Auto" Width="820" Height="Auto" MaxHeight="200">
<StackPanel Height="Auto" >
<controls:XRadGridView x:Name="UnitsGrid" ItemsSource="{Binding Units, Mode=OneWay}"
ScrollViewer.VerticalScrollBarVisibility="Auto"
MaxHeight="300"
IsReadOnly="True"
RowIndicatorVisibility="Collapsed"
CanUserInsertRows="False"
CanUserDeleteRows="False"
ShowColumnHeaders="False"
ShowGroupPanel="False"
CanUserResizeColumns="False"
CanUserReorderColumns="False"
AutoGenerateColumns="False">
<controls:XRadGridView.Columns>
<telerik:GridViewDataColumn Header="DUID"
DataMemberBinding="{Binding DisplayDuid}"
IsReadOnly="True"
Width="Auto" />
<telerik:GridViewDataColumn Header="ReasonTime">
<telerik:GridViewDataColumn.CellTemplate>
<DataTemplate>
<toolkit:TimePicker x:Name="ReasonTime"
VerticalAlignment="Center" HorizontalAlignment="Center" Width="20"
MaxWidth="20"
Loaded="ReasonTime_Loaded"
Format="HHmm"
Value="{Binding OfferHeader.ReasonTime, Mode=TwoWay}"
controls:TimePickerExtensions.UpdateBindingOnValueChanged="{Binding ApplyReasonToAll}"
TabIndex="0"/>
</DataTemplate>
</telerik:GridViewDataColumn.CellTemplate>
</telerik:GridViewDataColumn>
</controls:XRadGridView.Columns>
</controls:XRadGridView>
ViewModel code
Inside constructor I have below code
_reasonTimeChangedCommand = new DelegateCommand(OnReasonTimeChanged);
command details
private readonly DelegateCommand _reasonTimeChangedCommand;
public ICommand ReasonTimeChanged => _reasonTimeChangedCommand;
public void OnReasonTimeChanged()
{
}
The InvokeCommandAction should be inside the popup, to be used within the popup... but you bind to the value to a property (ReasonTime), and that property should be responsible for notifying the change. That's the view model's job, not just being a container for commands or forwarding properties from some DTO.
I created Carousel view that contains a Collection of Slides. Each slide contains and image, message, and Color. It is stored in an ObservableCollection. I have three colors in the collection. The first slide/page should be yellow, second should be Red, and third should be blue. The issue I have is, when the app initiates all of the slides are blue in the carousel. I need each slide/page to have different colors.
Carousel.ItemsSource = slides = new ObservableCollection<Slides>(new[]
{
new Slides("money", "Some Description", BackgroundColor = Color.Yellow),
new Slides("money", "Some Description2", BackgroundColor = Color.Red),
new Slides("money", "Some Description3",BackgroundColor = Color.Blue)});
<Control:CarouselViewControl x:Name="Carousel"
ShowIndicators="True"
BackgroundColor="{Binding Color}"
CurrentPageIndicatorTintColor="Black">
<Control:CarouselViewControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ContentView Grid.Row="0" Padding="60,30,60,0">
<Image Source="{Binding Image}" Aspect="AspectFit"/>
</ContentView>
<ContentView Grid.Row="1" Padding="20,50,20,0">
<Label Text="{Binding Message}" TextColor="black"
HorizontalOptions="CenterAndExpand"
FontSize="Large"/>
</ContentView>
</Grid>
</DataTemplate>
</Control:CarouselViewControl.ItemTemplate>
</Control:CarouselViewControl>
I expect each page to have different colors.
You are binding the BackgroundColor for the CarouselViewControl, which will set it for the whole view, not the distinct slides.
Furthermore, the items stored in ItemsSource do not represent any views in the CarouselViewControl, but rather data objects. Just because an object in the ItemsSource collection has a value BackgroundColor, the BackgroundColor of the respective view in the CarouselViewControl ain't set automagically.
To set the background of the pages you'll have to operate from within the DataTemplate and bind the BackgroundColor property of the Grid to the respective property of Slide.
<DataTemplate>
<Grid BackgroundColor="{Binding BackgroundColor}"> <!-- Bind the grids BackgroundColor to the one of the Slide -->
<!-- the grids content -->
</Grid>
</DataTemplate>
Most posts regarding DataGrid AutoGenerateColumns seem to deal with how to circumvent default behavior. Unfortunately the default is what I am struggling with.
I have several database tables created with Entity Framework 6.0, and would like to display them in my View using one and the same Datagrid for all tables, and AutoGenerating the Columns. Desired outcome: for the class-specific Viewmodel bound at run-time, display the columns with headers and at least one row.
XAML of the View's user control:
<UserControl.Resources>
<DataTemplate x:Key="TableDataTemplate">
<DataGrid
AutoGenerateColumns="True"
GridLinesVisibility="All"
HorizontalScrollBarVisibility="Visible"
VerticalScrollBarVisibility="Visible">
</DataGrid>
</DataTemplate>
</UserControl.Resources>
<StackPanel Height="720" Width="980">
<!-- shows user which menu item was chosen -->
<TextBlock Text="{Binding DisplayName}"/>
<!-- defines the Input data grid for adding to DB table -->
<Grid Height="80" MaxHeight="200">
<ItemsControl
ItemsSource="{Binding CurrentDataTable}"
ItemTemplate="{StaticResource TableDataTemplate}">
</ItemsControl>
</Grid>
The user control is bound to a class-specific 'Class'TableViewModel, implemented for all Database Tables. One example:
class ClientsAdminTableViewModel : TableViewModel
{
// the Property the view binds to
private IList<Client> currentDataTable;
public ObservableCollection<Client> CurrentDataTable
{
get { return CollectionExtensions.ToObservableCollection<Client>(currentDataTable); }
set { currentDataTable = value; OnPropertyChanged("CurrentDataTable")}
}
public ClientsAdminTableViewModel()
{
DisplayName = Strings.ClientAdminDisplayName;
currentDataTable = context.Clients.ToList<Client>();
}
When bound to {Binding CurrentDataTable} this code produces a UI, where I can see a grey body (probably the rows) surrounded by horizontal and vertical scrollbars, on top of which one long line (which must be the header line), but no columns.
Any help is appreciated.
your datagrid needs to have its itemsource set
try adding
ItemsSource="{Binding CurrentDataTable}"
to the datagrid declaration. Also, do you get any binding errors in the output window?
This code now works (Thank you J. King!) The trick was to get rid of the data template, create the data grid right in the grid with the exact same binding statements.
<StackPanel Height="720" Width="980">
<!-- shows user which menu item was chosen -->
<TextBlock Text="{Binding DisplayName}"/>
<!-- defines the Input data grid for adding to DB table -->
<Grid Height="200" MaxHeight="400">
<DataGrid
ItemsSource="{Binding CurrentDataTableNew}"
AutoGenerateColumns="True"
GridLinesVisibility="All"
HorizontalScrollBarVisibility="Visible"
VerticalScrollBarVisibility="Visible" >
</DataGrid>
</Grid>
</userControl>
I have a Silverlight 4 app created in MVVMLight.
In a view I have a DataGrid that is bound to my ViewModel, which has SeletedItem bound to SelectedItem again in my ViwModel :
<sdk:DataGrid Name="MyGrid" AutoGenerateColumns="False" Grid.Row="3" MaxHeight="200" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" RowHeight="35"
SelectedItem="{Binding SelectedItem, Mode=TwoWay, ValidatesOnNotifyDataErrors=False}" ItemsSource="{Binding Items}" >
This all works just as it should as in when I click on an item in the grid the SelectedItem in my ViewModel is set correctly.
Now I have added a button to the rows in the Datagrid and added an EventToCommand to the button which is bound to the same ViewModel:
<Button Content="Update" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<Command:EventToCommand Command="{Binding Source={StaticResource Locator}, Path=MainDialog.ButtonCommand, Mode=TwoWay}" />
</i:EventTrigger>
</i:Interaction.Triggers>
This command fires and works correctly The Problem Is the SelectedItem property that was set earlier, that I now want to use is set to null!!
Why is this EventToCommand resetting the SelecteedItem property and how do I stop it so I can use it???
you should shar your code to let us see what the problem is. But maybe problem is that you set selected item as object that isn't in your itemsource collection of datagrid. Try to set selecteditem like this
SelectedItem = Items.Where(x => x.Id == someId).First();
And see if this is the problem.. Ofcourse change condition in Where.. :)