Canvas UserControl DataContext update issue - wpf

I have developed a usercontrol, inside it has a canvas. I draw some lines and arcs in the canvas. Everytime when the datacontext changes, I need to force usercontrol's datacontext to null before updating new datacontext. Unless the new drawing is not getting updated. why is that? How to update Usercontrol's content (Actually canvas's content) without resetting the datacontext to null prior to update the new datacontext.
I use the following code. FlashControl is the usercontrol which contains canvas inside.
(FlashControl.Content as FrameworkElement).DataContext = null;
(FlashControl.Content as FrameworkElement).DataContext = this.DataContext;
FlashControl.DataContext = this.DataContext;
Update
::::::: This is my usercontrol
<UserControl x:Class="PricingRoutine.FlashGeneratorUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:Converters="clr-namespace:PricingRoutine.Converters"
xmlns:local ="clr-namespace:CustomFlashGenerator"
mc:Ignorable="d" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<UserControl.Resources>
<Converters:TextPositionConverter x:Key="TextPositionConverter" />
<Converters:LinetPositionConverter x:Key="LinePositionConverter" />
<Converters:PointPositionConverter x:Key="PointPositionConverter" />
</UserControl.Resources>
<Grid x:Name="MajorGrid" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ItemsControl ItemsSource="{Binding Path = CompositeObjectList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<!--<ViewBox Stretch="Uniform">-->
<Canvas x:Name="MainCanvas" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ClipToBounds="False">
<Canvas.RenderTransformOrigin>
<Point X="0.5" Y="0.5" />
</Canvas.RenderTransformOrigin>
<Canvas.RenderTransform>
<TransformGroup>
<TranslateTransform X="0" Y="0" /> <!--Handle this one through binding-->
<ScaleTransform ScaleX="1" ScaleY="1" CenterX=".5" CenterY=".5" /> <!--Handle this one through binding-->
</TransformGroup>
</Canvas.RenderTransform>
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type local:Line}">
<Line Stroke="Black" StrokeThickness="1">
<Line.X1>
<MultiBinding Converter="{StaticResource LinePositionConverter}" ConverterParameter="X1">
<Binding ElementName="MainCanvas" Path="ActualWidth" />
<Binding ElementName="MainCanvas" Path="ActualHeight" />
<Binding Path = "StartPoint.X" />
</MultiBinding>
</Line.X1>
<Line.Y1>
<MultiBinding Converter="{StaticResource LinePositionConverter}" ConverterParameter="Y1">
<Binding ElementName="MainCanvas" Path="ActualWidth" />
<Binding ElementName="MainCanvas" Path="ActualHeight" />
<Binding Path = "StartPoint.Y" />
</MultiBinding>
</Line.Y1>
<Line.X2>
<MultiBinding Converter="{StaticResource LinePositionConverter}" ConverterParameter="X2">
<Binding ElementName="MainCanvas" Path="ActualWidth" />
<Binding ElementName="MainCanvas" Path="ActualHeight" />
<Binding Path = "EndPoint.X" />
</MultiBinding>
</Line.X2>
<Line.Y2>
<MultiBinding Converter="{StaticResource LinePositionConverter}" ConverterParameter="Y2">
<Binding ElementName="MainCanvas" Path="ActualWidth" />
<Binding ElementName="MainCanvas" Path="ActualHeight" />
<Binding Path = "EndPoint.Y" />
</MultiBinding>
</Line.Y2>
</Line>
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
</Grid>
</UserControl>

Related

Syntax issue while multibinding on CanSelectNextPage of WizardPage-WPF

I would like to use multibinding on property of WizardPage called CanSelectNextPage.
WizardPage connects to Extended WPF toolkit package.
I did:
On MainWindow.xaml:
<xctk:WizardPage x:Name="Page1" PageType="Interior"
Title="DB Configuration-Stage 1"
Description="Select between create new GFACT environment to update existing gfact database"
Background="#FF27E0E0" BorderBrush="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"
Leave="Page1_Leave">
<WizardPage.CanSelectNextPage>
<MultiBinding Converter="{StaticResource CanSelectNextPage1}">
<Binding ElementName ="RadioButNew" Path="IsChecked" Mode="OneWay"/>
<Binding ElementName ="RadioButUpdate" Path="IsChecked" Mode="OneWay"/>
<Binding ElementName ="outputFolder" Path="Text" Mode="OneWay"/>
<Binding ElementName ="reducedModelFolder" Path="Text" Mode="OneWay"/>
</MultiBinding>
</WizardPage.CanSelectNextPage>
<Grid Margin="-5 -10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<RadioButton x:Name="RadioButNew" Content="New" Margin="5 10" FontSize="13.333"/>
<RadioButton x:Name="RadioButUpdate" Content="Update" Margin="5 10" Grid.Column="2" FontSize="13.333"/>
<Label x:Name="outputFolderLabel" Content="Select destination folder:" Height="30" Grid.Row="1" Grid.Column="0" FontSize="13.333" Margin="5 10">
<Label.Visibility>
<MultiBinding Converter="{StaticResource FilterConverter}">
<Binding ElementName ="RadioButNew" Path="IsChecked" Mode="OneWay"/>
<Binding ElementName ="RadioButUpdate" Path="IsChecked" Mode="OneWay"/>
</MultiBinding>
</Label.Visibility>
</Label>
<Label x:Name="reducedFolderLabel" Content="Select reduced model folder:" Height="30" Grid.Row="2" Grid.Column="0" FontSize="13.333" Margin="5 10 ">
<Label.Visibility>
<MultiBinding Converter="{StaticResource FilterConverter}">
<Binding ElementName ="RadioButNew" Path="IsChecked" Mode="OneWay"/>
<Binding ElementName ="RadioButUpdate" Path="IsChecked" Mode="OneWay"/>
</MultiBinding>
</Label.Visibility>
</Label>
<TextBox x:Name="outputFolder" Width ="200" Height="30" Grid.Row="1" Grid.Column="1" Margin="5 10">
<TextBox.Visibility>
<MultiBinding Converter="{StaticResource FilterConverter}">
<Binding ElementName ="RadioButNew" Path="IsChecked" Mode="OneWay"/>
<Binding ElementName ="RadioButUpdate" Path="IsChecked" Mode="OneWay"/>
</MultiBinding>
</TextBox.Visibility>
</TextBox>
<TextBox x:Name="reducedModelFolder" Width ="200" Height="30" Grid.Row="2" Grid.Column="1" Margin="5 10">
<TextBox.Visibility>
<MultiBinding Converter="{StaticResource FilterConverter}">
<Binding ElementName ="RadioButNew" Path="IsChecked" Mode="OneWay"/>
<Binding ElementName ="RadioButUpdate" Path="IsChecked" Mode="OneWay"/>
</MultiBinding>
</TextBox.Visibility>
</TextBox>
<Button x:Name="outputFolderOpenBut" Content="" Grid.Row="1" Grid.Column="2" Width="30" Height="30" VerticalAlignment="Top" Margin="5 10" >
<Button.Background>
<ImageBrush ImageSource="OpenPL.bmp" />
</Button.Background>
<Button.Visibility>
<MultiBinding Converter="{StaticResource FilterConverter}">
<Binding ElementName ="RadioButNew" Path="IsChecked" Mode="OneWay"/>
<Binding ElementName ="RadioButUpdate" Path="IsChecked" Mode="OneWay"/>
</MultiBinding>
</Button.Visibility>
</Button>
<Button x:Name="reducedModelFolderOpenBut" Content="" Grid.Row="2" Grid.Column="2" Width="30" Height="30" VerticalAlignment="Top" Margin="5 10" >
<Button.Background>
<ImageBrush ImageSource="OpenPL.bmp" Stretch="Uniform"/>
</Button.Background>
<Button.Visibility>
<MultiBinding Converter="{StaticResource FilterConverter}">
<Binding ElementName ="RadioButNew" Path="IsChecked" Mode="OneWay"/>
<Binding ElementName ="RadioButUpdate" Path="IsChecked" Mode="OneWay"/>
</MultiBinding>
</Button.Visibility>
</Button>
</Grid>
</xctk:WizardPage>
On MainWindow.xaml.cs:
public class CanSelectNextPage1 : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (values[0] is bool && values[1] is bool && values[2] is string && values[3] is string)
if (((bool)values[0] || (bool)values[1]) && (values[2] != null) && (values[3] != null))
{
return true;
}
return false;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
An error "Wizard Page is not supported in WPF" appeared on:
<WizardPage.CanSelectNextPage>
I'm assume it syntax issue- can someone help me please? I'm newbie on WPF..
It should be
<xctk:WizardPage.CanSelectNextPage>
<MultiBinding Converter="{StaticResource CanSelectNextPage1}">
<Binding ElementName="RadioButNew" Path="IsChecked" Mode="OneWay"/>
<Binding ElementName="RadioButUpdate" Path="IsChecked" Mode="OneWay"/>
<Binding ElementName="outputFolder" Path="Text" Mode="OneWay"/>
<Binding ElementName="reducedModelFolder" Path="Text" Mode="OneWay"/>
</MultiBinding>
</xctk:WizardPage.CanSelectNextPage>

WPF variable number of dragable objects that do not scale on resize

The Problem:
I have a non-fixed number of items to paint on a canvas with following requirement:
The items are complex: A circle with centered text, tooltips, some extra text arround.
The items may change during runtime (calls for Binding...)
The items have coordinates that need to be scaled to drawing coordinates (for example items with x coordinates in the range of from 500 to 5000 must be drawn on screen from 0 to 190)
The items itselves must not resize when the containing Canvas resizes. Only position of the item should resize.
For every item a horizontal and vertical grid line has to be drawn and the grid line has to be labeld at the axis.
The items should be draggable: The position should be updated in the underlying data.
I have a construction with ItemsControl which satisfis requirements 1, 2, 3, 4 and 5 but I have no idea about how to get it draggable and it's became rather complex and ugly.
I tried it whith ItemsSource with each a Canvas as ItemsPanel, positioning the items with a Style, Transforms and Converters.
The Questions:
How could this be done in another way, especially without a Style in the ItemsControl?
How can I get my items draggable?
My Code:
(In my Code, the property Points is the ObservableCollection if the to be drawn items)
Items template (exmaple, selected with a TemplateSelector):
<DataTemplate x:Key="inactiveViewableControlPointTemplate" DataType="{x:Type stationary:ViewableControlPoint}">
<Canvas LayoutTransform="{StaticResource horizontalFlipTransform}">
<Canvas.ToolTip>
<StackPanel>
<TextBlock Text="{Binding PointString, StringFormat={}Point {0}}"/>
<TextBlock Text="{Binding Speed, StringFormat={}Speed: {0}%}"/>
<TextBlock Text="{Binding Load, StringFormat={}Load: {0}%}"/>
<TextBlock Text="{Binding WeightsJoined, StringFormat={}Weigthingfactor: {0}}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding WeightsJoined}"
Value="{x:Static sys:String.Empty}">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
</Canvas.ToolTip>
<Path Stroke="Black" StrokeThickness="2" Fill="White">
<Path.Data>
<EllipseGeometry RadiusX="20" RadiusY="20" Center="0,0"/>
</Path.Data>
</Path>
<TextBlock Canvas.Bottom="0" Canvas.Left="0" TextWrapping="Wrap"
FontFamily="Helvetica" FontSize="10"
stationary:Mover.MoveToMiddle="Both" Text="{Binding Path=PointString}"/>
<TextBlock Canvas.Bottom="10" Canvas.Left="20" TextWrapping="Wrap"
FontFamily="Helvetica" FontSize="9" FontStyle="Italic"
Text="{Binding Path=WeightsJoined}" Background="#7fff"/>
</Canvas>
</DataTemplate>
The items (Points) ItemsControl, child of a general Canvas:
<ItemsControl Name="pointItems1" Canvas.Top="0" Canvas.Left="0"
ItemTemplateSelector="{StaticResource PointTemplateSelector}"
ItemSource="{Binding Points}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Width="{Binding ElementName=stationaryUI, Path=Width}" Height="{Binding ElementName=stationaryUI, Path=Height}">
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter">
<Setter Property="Canvas.Left">
<Setter.Value>
<MultiBinding Converter="{StaticResource ResourceKey=PositionTransformXConverter}">
<Binding ElementName="stationaryUI" Path="DataContext.Transform"/>
<Binding Path="X"/>
<Binding Path="Y"/>
</MultiBinding>
</Setter.Value>
</Setter>
<Setter Property="Canvas.Top">
<Setter.Value>
<MultiBinding Converter="{StaticResource ResourceKey=PositionTransformYConverter}">
<Binding ElementName="stationaryUI" Path="DataContext.Transform"/>
<Binding Path="X"/>
<Binding Path="Y"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
The PositionTransformConverters apply the transform and return either a Double or a Point. The Transform is held in the resources, could also be part of the DataContext's ModelView object.
The grid lines are painted with:
<ItemsControl Name="verticalLinesItems"
ItemsSource="{Binding Speeds}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Width="{Binding ElementName=stationaryUI, Path=Width}" Height="{Binding ElementName=stationaryUI, Path=Height}" >
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Line Stroke="Black" StrokeThickness="1" StrokeEndLineCap="Square">
<Line.X1>
<MultiBinding Converter="{StaticResource PositionTransformXConverter}" ConverterParameter="v X1">
<Binding ElementName="stationaryUI" Path="DataContext.Transform"/>
<Binding Path="Position"/>
<Binding Source="0"/>
</MultiBinding>
</Line.X1>
<Line.Y1>
<MultiBinding Converter="{StaticResource PositionTransformYConverter}" ConverterParameter="v Y1">
<Binding ElementName="stationaryUI" Path="DataContext.Transform"/>
<Binding Path="Position"/>
<Binding Source="0"/>
</MultiBinding>
</Line.Y1>
<Line.X2>
<MultiBinding Converter="{StaticResource PositionTransformXConverter}" ConverterParameter="v X2">
<Binding ElementName="stationaryUI" Path="DataContext.Transform"/>
<Binding Path="Position"/>
<Binding Source="100"/>
</MultiBinding>
</Line.X2>
<Line.Y2>
<MultiBinding Converter="{StaticResource PositionTransformYConverter}" ConverterParameter="v Y2">
<Binding ElementName="stationaryUI" Path="DataContext.Transform"/>
<Binding Path="Position"/>
<Binding Source="100"/>
</MultiBinding>
</Line.Y2>
</Line>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Speeds is a Property with only a get that iteerates over my Points items singles out duplicate entries in the x-axis. A comparable property exists for the y-axis. The labes are drawn like the grid lines, only with text instead of lines.
On Canvas resize, the Transform is updated and all ItemsControls repaint.

Get text value from custom ComboBox

I have a ComboBox defined as below:
<ComboBox Width="200" Height="30" Grid.Column="0" x:Name="ExistingSpeciesComboBox"
ItemsSource="{Binding SpeciesColorCollection}" HorizontalAlignment="Left">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Rectangle Fill="{Binding Path=Brush}" Stroke="Black" StrokeThickness="1" Height="15" Width="30"/>
<w:WTextBlock Text="{Binding Name}" VerticalAlignment="Center"
Foreground="{StaticResource SmallControlForegroundBrush}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
SpeciesColorCollection is an ObservableCollection of type ColorObject
Public Class ColorObject
Public Property Name As String
Public Property Brush As Brush
End Class
The ComboBox displays the items from the collection correctly but my problem is when I try to get the selected text from the ComboBox in a MultiBinding, I receive ColorObject instead of the name. How do I go about getting the value of the "Name" from within the WTextBlock of the ComboBox? The binding that I am using for my command is below. The converter is only returning strings.
<MultiBinding Converter="{StaticResource mySpeciesSetupConverter}">
<MultiBinding.Bindings>
<Binding ElementName="NewSpeciesName" Path="Text" />
<Binding ElementName="ExistingSpeciesComboBox" Path="Text" />
</MultiBinding.Bindings>
</MultiBinding>
<MultiBinding Converter="{StaticResource mySpeciesSetupConverter}">
<MultiBinding.Bindings>
<Binding ElementName="NewSpeciesName" Path="Text" />
<Binding ElementName="ExistingSpeciesComboBox" Path="SelectedItem.Name" />
</MultiBinding.Bindings>
</MultiBinding>

How do I set a Multibinding and Image in Expander Header

perhaps you can help me to solve this problem. I want to display a Text-Multibinding and an image in the header of my expander.
This is my simplified coding of the expander:
<Expander
x:Name="_myExpander">
<Expander.Header>
<MultiBinding
Converter="{StaticResource ExpanderHeaderConverter}">
<Binding
Path="Property1" />
<Binding
Path="Property2" />
<Binding
Path="Property3" />
</MultiBinding>
</Expander.Header>
<local:Content/>
</Expander>
How can I set an image in there?
thanks in advance!
Try this:
<Expander.Header>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding ...}"/>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource ExpanderHeaderConverter}">
<Binding Path="Property1" />
<Binding Path="Property2" />
<Binding Path="Property3" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</Expander.Header>

XAML Tool Tip Data Context and Multi Binding

I have a ListView in my XAML and I am trying to hook up a MultiBinding Converter.
<ListView
Grid.Column="4"
Grid.Row="1"
Grid.RowSpan="5"
Margin="8,0,8,8"
HorizontalAlignment="Stretch"
Name="lvDisplayType"
ItemsSource="{Binding Path=Types}"
SelectedItem="{Binding Path=Current.Opt}"
VerticalAlignment="Stretch"
SelectionChanged="lvType_SelectionChanged"
SelectionMode="Single"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.ItemTemplate>
<DataTemplate>
<DockPanel
HorizontalAlignment="Center">
<TextBlock
Text="{Binding Path=., Converter={StaticResource DisplayConverter}}"
HorizontalAlignment="Center"
Padding="6"
VerticalAlignment="Center"
TextWrapping="Wrap">
<TextBlock.ToolTip>
<ToolTip DataContext="{Binding Path=Current}">
<MultiBinding Converter="{StaticResource OptConverter}">
<Binding Path="Opt" />
<Binding Path="Type" />
</MultiBinding>
</ToolTip>
</TextBlock.ToolTip>
</TextBlock>
</DockPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The code not working is:
<TextBlock.ToolTip>
<ToolTip DataContext="{Binding Path=Current}">
<MultiBinding Converter="{StaticResource OptConverter}">
<Binding Path="Opt" />
<Binding Path="Type" />
</MultiBinding>
</ToolTip>
</TextBlock.ToolTip>
At present the Converter is returning an empty string as both 'values[0] == System.Windows.DependencyProperty.UnsetValue' and 'values[1] == System.Windows.DependencyProperty.UnsetValue' return true. These values are never set.
Because of the logical tree (I think) the TextBlock.ToolTip default binding is 'Current.Opt'. For the MultiBinding I also need to refer to 'Type' which is another property of 'Current'. So to get around this I have set 'ToolTip DataContext="{Binding Path=Current}"' - this isn't working as expected - what am I doing wrong?
I know I could do this easily in the Code behind, but we are employing MVVM, so would like to avoid it if possible.
Any help greatly appreciated!
Thank you
Try to do it in this way,
1.Does this give DependencyProperty.UnsetValue in the Converter? Otherwise, what is coming in to the converter?
<TextBlock.ToolTip>
<MultiBinding Converter="{StaticResource OptConverter}">
<Binding RelativeSource="{RelativeSource Self}" />
<Binding RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</TextBlock.ToolTip>
2.Does this give DependencyProperty.UnsetValue in the Converter?
<TextBlock.ToolTip>
<MultiBinding Converter="{StaticResource OptConverter}">
<Binding RelativeSource="{RelativeSource Self}" Path="Current"/>
<Binding RelativeSource="{RelativeSource Self}" Path="Current"/>
</MultiBinding>
</TextBlock.ToolTip>

Resources