An error occurred when using binding in C# - c#

<ListView Margin="6,6,5,7" x:Name="lvBB" Foreground="Black" >
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel Orientation="Vertical" Margin="10" Background="{Binding SelectedNotamColor}">
<WrapPanel Orientation="Horizontal">
<TextBlock Text="{Binding Priority}" FontWeight="Bold" FontSize="18"/>
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Background" Value="{Binding SelectedNotamColor, mode=Toway}"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
I am binding a json object which has the property called SelectedNotamColor, if I use it in the ListView.ItemContainerStyle setter, when I try to save my json object into a text file it will occur an error like this
System.InvalidOperationException:the object is being used
and when I delete the setter property, it will come back to normal.
How to solve this problem or is there any other way to bind my ListView items' color?

You have syntax error in your style setter property.
Try to replace
mode=Towway
with
mode=TwoWay
I coudn't find line of code where you fill items of your listbox.
For example, in XAML:
ItemsSource="{Binding YourListOfJsonObjects}
or code behind:
lvBB.ItemsSource = YourListOfJsonObjects

Related

how to select the item of list veiw data template in wpf?

I made a list view, and i used a data Template as you seeing
below and now i want to select the Which item,the user selected and put the text of the selected item textblock to a variable
<ListView.ItemTemplate>
<DataTemplate >
<Border CornerRadius="20"
BorderThickness="2"
BorderBrush="Red"
Width="70"
Height="70"
Margin="5,5">
<Button x:Name="calender_btn"
Background="Transparent"
BorderBrush="Transparent"
Style="{StaticResource calender_btn_style}"
Click="calender_btn_Click">
<TextBlock x:Name="calender_txt_block"
Text="{Binding _outputdate}"
Foreground="White"
Width="55"
FontSize="14"
Margin="3,5"
TextWrapping="Wrap"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextAlignment="Center"
>
</TextBlock>
<Button.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="20"/>
</Style>
</Button.Resources>
</Button>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
I have no idea how I can do it, because I am new in wpf, if you know how I can do it.
Depending on how your data looks like, you probably get a data object to each button that contains the text. You can find that object in the buttons data context.
private void calender_btn_Click(object sender, RoutedEventArgs e)
{
var dataObject = ((Button)sender).DataContext;
}
If you are using ItemsSource you can get the selected value by binding to ListView SelectedItem (SelectedValue in some cases).
SelectedItem="{Binding SelectedData, Mode=TwoWay}"
Assuming that you have SelectedData property in your DataContext with same type as your data in the shown collection.
Google for MVVM

How to set animations/transitions when adding elements to a ListViews?

I have got a ListView wich I added Elements by binding. The ListView looks like:
<ListView
x:Name="ListView"
Height="auto"
Width="350"
ItemsSource="{Binding}"
Padding="0,0,-20,0"
Grid.Row="1"
Grid.Column="0"
Background="#EFEFEF"
ItemContainerStyle="{StaticResource ListViewStyle}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Height="50" VerticalAlignment="Top" Margin="0,0,0,0"
<TextBlock Text="{Binding name} TextWrapping="NoWrap"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
With this basic setup there is already an animation when a element is bonded to the underlying List. Strangely to different animations are used. The first element slides in from the right and all other elements popup. I’m searching for a way to animate all added elements the same way (e.g. slide in from the right). I have been locking into the auto generated (by Blend) ListViewStyle for hours now but couldn't find something. Later I found out that it is possible to add this property inside the style:
<Style x:Key="ListViewStyle" TargetType="ListViewItem">
<Setter Property="Transitions">
<Setter.Value>
<TransitionCollection>
<EntranceThemeTransition FromHorizontalOffset="400" />
<PopupThemeTransition FromHorizontalOffset="400"/>
</TransitionCollection>
</Setter.Value>
</Setter>
...
</Style>
The EntranceThemeTransition and PopupThemeTransition seems to be the right properties because they change the behavior of the animation. But I don't know how to use them or how to disable one. How can I get just one animation (slide in from the right) to the ListView?
This should work:
<ListView
x:Name="lv">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel>
<VirtualizingStackPanel.ChildrenTransitions>
<TransitionCollection>
<EntranceThemeTransition
FromHorizontalOffset="400" />
</TransitionCollection>
</VirtualizingStackPanel.ChildrenTransitions>
</VirtualizingStackPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
*Update:
You can also use ListView.ItemContainerTransitions to define these transitions.

Access a control from within a DataTemplate with its identifying name

In my WPF application I have a ComboBox control that is located inside a Grid Control. In XAML I am assigning a name to the ComboBox:
<DataGridTemplateColumn Header="Status">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock VerticalAlignment="Center" Text="{Binding name_ru}" Width="Auto" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox Name="stcom" Style="{DynamicResource ComboBoxStyle}" SelectionChanged="status_SelectionChanged" Height="auto" Width="Auto">
<ComboBox.BorderBrush>
<SolidColorBrush Color="{DynamicResource Color1}"/>
</ComboBox.BorderBrush>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
With the method FindName(string) I am trying to refer to the ComboBox with its associated name:
ComboBox stcom
{
get
{
return (ComboBox)FindName("stcom");
}
}
if (stcom != null)
{
stcom.ItemsSource = list;
}
But obviously the control can not be found because the reference stcom remains null.
The question now is how to refer to my ComboBox using its name property ?
The answer is:
<Style x:Key="CheckBoxStyle1" TargetType="{x:Type CheckBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<StackPanel Orientation="Horizontal">
<Grid>
<TextBlock Name="tbUserIcon" Text="t1" />
<TextBlock Name="tbCheck" Text="✓" />
</Grid>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
and C#:
checkBox.ApplyTemplate();
var tbUserIcon= (TextBlock)checkBox.Template.FindName("tbUserIcon", checkBox);
don't forget the checkBox.ApplyTemplate() be fore Template.FindName() it's important!
First you have to get access to the control template which it has been applied to, then you can find an element of the template by name.
Have a look at the MSDN knowledge base :
How to: Find ControlTemplate-Generated Elements
You can't access controls that are part of a DataTemplate with their name.
You can try to read about some workarounds for example
WPF - Find a Control from DataTemplate in WPF
You can also have a look at the dozens of posts here on SO issuing this topic for example
here
here
here
here
here
here
here
here

how to switch views according to command

I've a main view and many usercontrols.
The main view contains a two column grid, with the first column filled with a listbox whose datatemplate consists of a usercontrol and the second column filled with another usercontrol. These two usercontrols have the same datacontext.
MainView:
<Grid>
//Column defs
...
<ListView Grid.Column="0" ItemSource="{Binding FooList}">
...
<DataTemplate>
<Views: FooView1 />
</DataTemplate>
</ListView>
<TextBlock Text="{Binding FooList.Count}" />
<StackPanel Grid.Column="1">
<Views: FooView2 />
</StackPanel>
<Grid>
FooView1:
<UserControl>
<TextBlock Text="{Binding Foo.Title}">
</UserControl>
FooView2:
<UserControl>
<TextBlock Text="{Binding Foo.Detail1}">
<TextBlock Text="{Binding Foo.Detail2}">
<TextBlock Text="{Binding Foo.Detail3}">
<TextBlock Text="{Binding Foo.Detail4}">
</UserControl>
I've no IDE here. Excuse me if there is any syntax error
When the user clicks on a button. These two usercontrols have to be replaced by another two usercontrols, so the datacontext changes, the main ui remaining the same.
ie, FooView1 by BarView1 and FooView2 by BarView2
In short i want to bind this view changes in mainview to my command (command from Button)
How can i do this?
Also tell me if i could merge the usercontrol pairs, so that only one view exists for each viewmodel
ie, FooView1 and FooView2 into FooView and so on...
Though I am still not sure whether I got you, I suggest the following.
In your example it looks like you want to show the details of the Foo object. The datacontext stays the same. Maybe you can set Visibility-Flags in your viewmodel to decide what you want to display. This can be done using the command that is executed by your button.
FooView:
<UserControl>
<TextBlock Text="{Binding Foo.Title}"
Visibility="{Binding ShowTitle}">
<TextBlock Text="{Binding Foo.Detail1}"
Visibility="{Binding ShowDetails}">
<TextBlock Text="{Binding Foo.Detail2}"
Visibility="{Binding ShowDetails}">
<TextBlock Text="{Binding Foo.Detail3}"
Visibility="{Binding ShowDetails}">
<TextBlock Text="{Binding Foo.Detail4}"
Visibility="{Binding ShowDetails}">
</UserControl>
Is this a possible solution?
If you want to change the datatemplate you might do something like this:
FooView (2nd version)
<UserControl>
<UserControl.Resources>
<DataTemplate x:Key="dataTemplate1">
<TextBlock Text="{Binding Foo.Title}">
</DataTemplate>
<DataTemplate x:Key="dataTemplate2">
<TextBlock Text="{Binding Foo.Detail1}">
<TextBlock Text="{Binding Foo.Detail2}">
<TextBlock Text="{Binding Foo.Detail3}">
<TextBlock Text="{Binding Foo.Detail4}">
</DataTemplate>
</UserControl.Resources>
<Style x:Key="Default">
<Style.Triggers>
<DataTrigger Binding="{Binding Foo.ShowFooView}" Value="1" >
<Setter Property="Template" Value="{StaticResource dataTemplate1}" />
<DataTrigger>
<DataTrigger Binding="{Binding Data.ShowFooView}" Value="2" >
<Setter Property="Template" Foo="{StaticResource dataTemplate2}" />
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl>
The idea is, that depending on the property Foo.ShowFooView you decide which data template should be used. Of course the type Foo should implement INotifyPropertyChanged to notify the UI.
Sorry, but I don't get the point. To answer your question you need to provide more information.
Do you want to change your datacontext by replacing a usercontrol?
Why don't you use different datatemplates for different target types?
Maybe you can provide some code snippets.

WPF: Is it possible to convert the following code from Procedural (C#) to Declarative (XAML)?

I have the following content in a Window (removed unnecessary sections):
XAML:
<Style x:Key="itemstyle" TargetType="{x:Type ContentPresenter}">
<EventSetter Event="MouseLeftButtonDown" Handler="HandleItemClick"/>
</Style>
<ItemsControl ItemsSource="{Binding ArtistList}" Margin="10" Name="artist_list" ItemContainerStyle="{StaticResource itemstyle}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ID}" Foreground="White"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Controls:RSSViewer x:Name="rssControl" />
C# (Code Behind):
private void HandleItemClick(object sender, MouseButtonEventArgs e)
{
var selectedArtist = ((ContentPresenter) sender).Content as Artist;
rssControl.SourceUrl = "http://agnt666laptop:28666/rss.aspx?artistid=" + selectedArtist.ID;
}
Now what I want to do is convert the above mixture of xaml and C# to something that is purely and solely xaml, to take advantage of WPF's DataBinding model.
I think that it requires something like an Event trigger and combination of data binding with the selected item of the itemscontrol element or something like that, but I'm not sure on how to go about it.
Can anyone guide me to how I can convert the above solution to remove the procedural code?
If you are using .NET 3.5SP1, you can probably use the new StringFormat binding markup extension to do it. See here for examples of binding with StringFormat.
If .NET 3.5SP1 is not an option, then you'll probably have to create your own ValueConverter. Bind the value of the SourceUrl property to the selected artist's ID, and then in your converter return the same string that you're using in the C# sample above.
<ItemsControl ItemsSource="{Binding ArtistList}" Margin="10" Name="artist_list" ItemContainerStyle="{StaticResource itemstyle}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ID}" Foreground="White"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Controls:RSSViewer x:Name="rssControl" SourceUrl="{Binding SelectedItem.ID, ElementName=artist_list, StringFormat= 'http://agnt666laptop:28666/rss.aspx?artistid={0}' }" />

Categories