What would be an alternative to x:Reference? - wpf

I have XAML that looks as follows:
<DataTemplate x:Key="CdTeThickness">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row = "0" Orientation="Horizontal">
<CheckBox x:Name="DisplayMarkers" Content="Display Data Points" Margin="8,5,0,5" HorizontalAlignment="Left" IsChecked="False"/>
<CheckBox x:Name="DisplayIndicator" Content="Display Indicator" Margin="8,5,0,5" HorizontalAlignment="Left" IsChecked="False"/>
</StackPanel>
<vf:Chart Grid.Row = "1" Style="{StaticResource chartStyle}" IndicatorEnabled="{Binding Source={x:Reference DisplayIndicator}, Path=IsChecked}">
<vf:Chart.Titles>
<vf:Title Text="{Binding Chart.ChartTitle}"/>
</vf:Chart.Titles>
My understanding is that x:Reference is not widely supported yet. However, this is the only way I was able to bind to the desired property (DisplayIndicator), as shown in the screen shot. Can someone suggest an alternative to x:Reference that will work in this situation?

Often you can use an ElementName binding, however x:Reference is actually well supported.
{Binding IsChecked, ElementName=DisplayIndicator}

Also, as an alternative to direct binding, you could bind both the Checkbox.IsChecked and the Chart.IndicatorEnabled enabled to a property (e.g. ChartDisplayMarkers) on your viewmodel.

Related

Visual studio like search

I want to implement Visual Studio like search. For now I want to make it search my UserControls, and on click it should open them in Tab.
I'm not searching for code, just for the right guidelines and the right terminology to try to implement this.
Thanks for any advice.
Example:
For searching in your UserControl collection I would use LINQ.
List<UserControl> results = (from UserControl control in list_of_usercontrols where (control.SomeParameter.ToLower().Contains(SearchParameter) || control.OtherParameter.ToLower().Contains(SearchParameter)) && nnn.IsEnabled select nnn).Distinct().ToList();
For displaying results I highly recommend ListView. I use it to show results in my WPF app, it's incredibly fast.
listView1.ItemsSource = results;
You can set ItemTemplate for your ListView.
<ListView Grid.Row="1" Name="listView1" BorderThickness="0" SelectionMode="Single" >
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label FontSize="15" >
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding SomeProperty}"></TextBlock>
<TextBlock Text="{Binding OtherProperty}"></TextBlock>
<TextBlock Text="{Binding ThirdProperty}" ></TextBlock>
</StackPanel>
</Label>
<Label Content="{Binding FourthProperty}" Grid.Row="1" Padding="5,0,0,5"></Label>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

Grief with WPF UserControl with ListBox and TextBox Can't get textwrapping to work

I am trying to produce a simple User Control that allows a user to enter notes and review the notes he or she has taken. For now, I have a ListBox to show previous notes and a TextBox to enter a new note. The ListBox also uses TextBoxs to show the individual notes. The logic is all working. Now I'd just like the control to look a little nicer. I am not seeing text wrapping when one of the notes is long. Nor am I seeing text wrapping on the TextBox where I enter a new note. I have tried to research this and have found the warnings about using StackPanels. Hence no stack panels here! Here is my XAML
<UserControl.Resources>
<DataTemplate x:Key="DefaultTemplate">
<Grid x:Name="GridItem" >
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBox x:Name="NoteText" Grid.Column="0" Margin="0,5,5,0" Text="{Binding Path=NoteText}" TextWrapping="Wrap" />
</Grid>
</DataTemplate>
</UserControl.Resources>
<Grid Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Text="{Binding Path=NewNoteText, UpdateSourceTrigger=PropertyChanged}" LostFocus="TextBox_LostFocus">
<TextBox.InputBindings>
<KeyBinding Command="{Binding Path=AddNote}" Key="Enter"/>
</TextBox.InputBindings>
</TextBox>
<ListBox Grid.Row="1" ItemsSource="{Binding Path=Notes}" Margin="5" ItemTemplate="{DynamicResource DefaultTemplate}" SelectionChanged="NotesControl_SelectionChanged">
</ListBox>
</Grid>
I have tried specifying Width="*" in the UserResources. That made no difference. I don't really want to specify a maximum width for either TextBox if I can help it.
And here is how I use it in the main test form:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" ></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition ></RowDefinition>
</Grid.RowDefinitions>
<ctrlLib:RecordingListControl Grid.Row="0" Name="_ctrlRecordings"
PatientIdAndSessionNumber="{Binding PatientIdAndSessionNumberMain, Mode=TwoWay}"
SelectedItem="{Binding SelectedItemMain, Mode=OneWayToSource}" />
<Label Grid.Row="1" Content="{Binding SelectedItemMain.RecordingName}" />
<ctrlLib:NotesControl Grid.Row="2" Name="_ctrlNotes" PatientIdAndSessionNumber="{Binding PatientIdAndSessionNumberMain, Mode=TwoWay}" />
</Grid>
Any ideas? I get the general idea that nothing is telling the TextBox that it's width is constrained so no TextWrapping is invoked, but I'm at a loss as to how to tel the TextBox that there is a width constraint. I've seen all sorts of posts about not using "Auto" and using "*" but nothing seems to work!
Looking ahead, I'm not really happy with how this looks period. I'm currently getting a line drawn around every note item which I don't like. Also, I'd like the textbox where you enter the new note to look like part of the listbox and appear at the bottom.
Thanks,
Dave

XAML ListView Items IsEnabled

I have the following XAML :
<Grid Grid.Row="3" Margin="8,8">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Setting 'UsingItems' here -->
<CheckBox Grid.Row="0"
IsChecked="{Binding Path=UsingItems}"
Content="{Binding Path=IncludeItemsText}" />
<!-- This works as expected -->
<CheckBox Grid.Row="1"
IsEnabled="{Binding Path=UsingItems}"/>
<!-- This doesn't! Even though the ListView becomes enabled the Items aren't and the Checkboxes are not checkable! -->
<ListView Grid.Row="2" IsEnabled="{Binding Path=UsingItems}"
VerticalAlignment="Stretch"
ItemsSource="{Binding Path=SortedItems}">
<ListView.ItemTemplate>
<DataTemplate>
<DockPanel>
<CheckBox
IsChecked="{Binding Path=.IsSelected}"
Margin="0,2" Click="CheckBox_Click" />
<TextBlock
Text="{Binding Path=.Item.ItemDescription}"
Margin="4,0,0,0"
VerticalAlignment="Top">
</TextBlock>
</DockPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
I would like to Disable all Items in the ListView if the property 'UsingItems' = false. 'UsingItems' is set using the Checkbox in Row 0, I've confirmed this is working by having a dummy Checkbox in Row 1 - the 'IsEnabled' property is set as expected.
However, the ListView Items remain disabled when 'UsingItems' = true, even though the ListView becomes enabled (and the items 'look' enabled).
I had assumed the IsEnabled property would filter down the tree - but this is not happening here.
Where am I going wrong?
Thanks
Joe

Find datacontext inside datatemplate

I'm not a Silverlight expert and I'm struggling with an irritating problem.
I have a Telerik RadRichTextbox inside a Grid. This Grid is inside a DataTemplate which is part of an ItemsControl. Like so:
<ItemsControl Grid.Row="1" ItemsSource="{Binding MyCollection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<telerik:RadRichTextBox x:Name="_Editor" DocumentChanged="HandleditorDocumentChanged"/>
<Xaml:XamlDataProvider x:Name="xamlProvider" Xaml="{Binding Text}" RichTextBox="{Binding ElementName=_Editor}" />
<TextBox Grid.Row="1" Text="{Binding Text2}" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
In the DocumentChanges event I want to access the DataContext of the DataTemplate. I tried setting the DataContext of the _Editor to {Binding} but in the code behind the DataContext is null.
I then thought of getting the parent of the _Editor, which is the Grid. Its DataContext is also null and the Grid its parent is also null.
Any ideas?
I think what' you're looking for is a DataContext Proxy. Consider this example:
http://weblogs.asp.net/dwahlin/archive/2009/08/20/creating-a-silverlight-datacontext-proxy-to-simplify-data-binding-in-nested-controls.aspx

Source versus DataContext in XAML

Which of these methods is best?
<Window.Resources>
<sys:Int16 x:Key="MyValue">123</sys:Int16>
</Window.Resources>
<StackPanel>
<!-- method 1 -->
<TextBlock Text="{Binding}" DataContext="{StaticResource MyValue}" />
<!-- method 2 -->
<TextBlock Text="{Binding, Source={StaticResource MyValue}}" />
</StackPanel>
As with many "which is better" questions. I would say that "it depends" on the context.
They both exist because they both can serve a purpose in different contexts. Given only what you have shown above, I would choose Example 2.
When you set the DataContext, however, all of its children will inherit that DataContext. So maybe instead you are using a Button. And within you Button, you want to jazz it up a bit and display the text four times each with a different color. As you can see below, I would then choose Example 1.
Example 1: (note the DataContext is on the button, and the TextBlocks don't need the Source like they do in Example 2)
<Button DataContext="{StaticResource MyValue}" Height="Auto" Width="Auto" HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding}" Foreground="Red" />
<TextBlock Grid.Row="1" Grid.Column="0" Text="{Binding}" Foreground="Blue" />
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding}" Foreground="Yellow"/>
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding}" Foreground="Green" />
</Grid>
</Button>
Example 2:
<Button Height="Auto" Width="Auto" HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding, Source={StaticResource MyValue}}" Foreground="Red" />
<TextBlock Grid.Row="1" Grid.Column="0" Text="{Binding, Source={StaticResource MyValue}}" Foreground="Blue" />
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding, Source={StaticResource MyValue}}" Foreground="Yellow"/>
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding, Source={StaticResource MyValue}}" Foreground="Green" />
</Grid>
</Button>
When you're binding to a simple object that only has one representation like an Int16 in your case, you're probably only going to bind and display that value once, and thus option 2 makes most sense.
A good rule of thumb... if you find yourself setting the 'Source' to the same thing more than one binding, you should probably just bind the DataContext of a common parent FrameworkElement.
I would say that if I had to choose between the two, I would go with method 2. DataContext is really more for Databinding an item to a more complex underlying object and eases the databinding of many data values.
Just out of curiosity, why are you doing it this way? Does your code change the value of MyValue at some point? Is there no better way for you to do it for some reason?
The DataContenxt DependencyProperty allows you to easily bind across all of proeprties for a DependencyObject.
The Source DependenceyProperty of a Binding allows you to point that specific binding to the source you want, regardless of the DataContext.
This becomes really helpful when you are doing more complex bindings for ListViews. For instance:
<Window.Resources>
<local:MyConverter x:Key="MyConverter" />
</Window.Resources>
<Grid>
<ComboBox ItemsSource="{Binding Source={StaticResource MyConverter}, Path=DisplayValues}" DataContenxt={Binding ElementName=lvwItems Path=SelectedItem} SelectedItem="{Binding Converter={StaticResource MyConverter}"/>
<ListView Name="lvwItems"......
The above example just shows off that I set the itemssource to a property in the 'MyConverter' called DisplayValues, the datacontext is what I am working with on that combobox though, which is handling the SelectedItem property of the ListView named 'lvwItems'.
Hope this helps.

Resources