ListBox with copy paste feature - wpf

I am using MVVM approach, my UI needs to provide a simple copy paste area (something like TextBox) to the user and once user enters the text, I need to convert all newline separated text into list items - list items because I want to highlight individual items with errors, if any.
It should be seamless for the user- user should only see List items and should be able to edit them later.
Hence, basically I need a ListBox (for the programmer) which acts like a textbox (for the user). How can I achieve this?
I have implemented this using a Grid with TextBox & ListBox in the same Row, but with some overlap so that user can paste text in textbox and as soon as user enters the text, viewmodel separates the newlines into listitems. It is working but I am facing many issues (like clearing the textbox, etc.). I am looking for better more efficient solution if any. Below is the code snippet from xaml:
<Grid>
<TextBox AcceptsReturn="True" VerticalAlignment="Stretch" BorderBrush="Transparent"
Text="{Binding TextBoxData, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}">
<TextBox.InputBindings>
<KeyBinding Key="Enter" Command="{Binding OnNewLineCommand}"/>
</TextBox.InputBindings>
</TextBox>
<ListBox ItemsSource="{Binding ListBoxItems}" Margin="0,20,0,0" BorderBrush="Transparent" FocusVisualStyle="{x:Null}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding}" BorderBrush="Transparent"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListBox>
</Grid>
Thanks,
RDV

Related

How to handle Validations on Custom Control

I recently wrote my first custom control, an autocomplete textbox. Its Controltemplate consists of something like this
<Grid >
<Border/>
<TextBlock x:Name="Label"/>
<TextBox x:Name="TextLabel"/>
</Grid>
The first Textblock is used as a Label, the second one shows the content. The TextLabel binds on an Object, let's call it Customer If the underlying search doesn't find a Customer object, I want to show the errortemplate. When defining the TextLabel like this
<TextBox x:Name="PART_Editor"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Validation.ErrorTemplate="{DynamicResource ValidationErrorTemplate}"
Style="{StaticResource TransparentTextBoxStyle}"
Text="{Binding Path=Text, RelativeSource={RelativeSource Mode=TemplatedParent},
Mode=TwoWay, ValidatesOnNotifyDataErrors=True,
NotifyOnValidationError=True,
ValidatesOnDataErrors=True,
UpdateSourceTrigger=PropertyChanged}" >
</TextBox>
the Validation is made and the error template of the textbox is shown. Unfortunately the Red Border is only around the inner TextBox and not around the whole custom control which looks just not good.
I was wondering how to achieve two things:
How can the ErrorTemplate of the CustomControl be triggered when one of the child-validations fail?
Do I have to specify all these NotifyOnValidationerror properties or is it possible to catch all errors on entity level and show the same ErrorTemplate
If you need additional Information, please just ask

SelectionChanged event not raised

Is there a way to fix the known bug of Selection Change Event, selecting does not work if the same item is tapped again.
to give further background, my scenario is that I have four items in my pivot page and when I click one of those items i will be navigated to another page. Now my dilemma is that when i select the same items again, navigation does not work or nothing happens.
Please let me know your suggested fix, thanks much in advance.
<ListBox x:Name="lbviewlist" ItemsSource="{Binding items}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="selectionchanged">
<Command:EventToCommand Command ="{Binding ItemListCommand }" PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock TextWrapping="Wrap" Text="{Binding itemName}" FontSize="30" Margin="10,0,0,0" Style="{StaticResource PhoneTextTitle2Style}" Foreground="CadetBlue"/>
<TextBlock TextWrapping="Wrap" Text="{Binding itemDescription}" FontSize="20" Margin="15,5,0,10"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
A good alternative approach is to include all of the content in each item inside a button, which is styled to be invisible so that you never see it, but it covers the surface of the item it encapsulates. If you're using MVVM you can bind the same command property to each of your 'buttons' and bind the DataContext of the button (your data item) to the command parameter. Then whenever you click an item you'll get the command firing every time.
You might want to change your items control to something simple so that the selection changed events dont get in the way.

Silverlight ListBox custom keyboard selection behavior

I am customizing a templated multi-selection-enabled ListBox and can't easily implement the following feature - if there is only one item selected which is also current (focused), when user navigates up or down the list the selection should follow current item. I tried to subscribe to GotFocus event of the DataTemplate's StackPanel, but apparently I don't receive those events (even though MouseEnter/MouseLeave work).
I guess I could do it by modifying a somewhat similar behavior, but isn't there an easier way? This looks like a pretty basic behavior to me...
<ListBox>
<ListBox Name="lbItems" SelectionMode="Multiple">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
MouseEnter="UIElement_OnMouseEnter"
MouseLeave="UIElement_OnMouseLeave"
GotFocus="UIElement_OnGotFocus">
<Rectangle Width="15" Height="15" Fill="{Binding Path=Brush}" />
<TextBlock Text="{Binding Path=Category}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Multiline Combobox in WPF

I'm trying to find an example of a multi line user editable combobox for WPF. We've tried various things with a custom template but can't make it work. The specific problem we're trying to solve is displaying a list of addresses in a drop down where the user can type in new ones at the same time. Typing into a combobox is no problem.. multi line is killing us though.
If we want show Textbox in ComboBox we can override the ItemTemplate of ComboBox. And to display multiline text we can set AcceptReturn="True" for TextBox.
<ComboBox Width="250" Height="30" >
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBox AcceptsReturn="True" Width="200" Height="100"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Is this what you need or am I missing something?

WPF: Problem with ItemsControl datatemplate as a user control

This works fine:
<ItemsControl ItemsSource="{Binding Persons}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=FirstName}"/>
<TextBlock Text="{Binding Path=LastName}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
But, I want to make use of a User Control in place of the stack panel with two TextBlocks using something like:
<DataTemplate>
<jasControls:NameView/>
</DataTemplate>
But, with this and a million other syntaxes, the NameView shows nothing, yet it works fine in a separate test, outside the ItemsControl, with explicitly set (dependency) property - e.g.
<jasControls:NameView FName="{Binding Path=Person.FirstName}" />
I can find hardly any examples of this anywhere, and need to know how to specify the properties of the user control - or how can the user control 'receive' the individual item type (a Person)? What syntax to use? Do I need to specify the datatype? Is ItemsControl causing a problem or should any similar control do e.g. ListBox? Can I design it so that the user control gets an entire Person object? What dependency properties do I need in the user control? In short, how to get data into the user control?! The actual business types involved will be a bit more complicated involving some logic in the user control, hence my desire to use a user control.
ANY direction on this will be very gratefully received - TIA
Assuming your Persons collection has many Person objects in it, the DataContext property of your NameView control will automatically be set to the Person object.
You wouldn't need any dependency properties to achieve this feat. Your NameView usercontrol would simply be:
<UserControl ...>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FirstName}"/>
<TextBlock Text="{Binding LastName}"/>
</StackPanel>
</UserControl>
You should have no codebehind to get this information to display.
From there, you should be able to access the Person object from the DataContext property:
Person person = this.DataContext as Person;

Resources