I have a style in XAML which works fine but now I have to create this style in the code behind. My problem is with setting the binding to the value of templated parent which is the CellValuePresenter(<Binding Path="Value" RelativeSource="{RelativeSource TemplatedParent}"/>) This value is being passed as null to my ValueConverter. The other bound value is being passed fine. How can I do this in code behind? I've pasted relevant code sections below.
the XAML
//<Style x:Key="cvpStyle" TargetType="{x:Type igDP:CellValuePresenter}"> //<Setter Property="Template"> // <Setter.Value> // <ControlTemplate TargetType="{x:Type igDP:CellValuePresenter}"> // <Rectangle Name="myRectangle"> // <Rectangle.Fill> // <VisualBrush> // <VisualBrush.Visual> // <Label> // <Label.Content> // <MultiBinding Converter="{StaticResource cvpValueChangeConverter}"> // <Binding Path="Value" RelativeSource="{RelativeSource TemplatedParent}"/> // <Binding Path="SelectedItem" ElementName="lbOfferBidFormat" />
the C# code (the binding section)
MultiBinding multiBinding = new MultiBinding(); multiBinding.Converter = FindResource("cvpValueChangeConverter") as IMultiValueConverter;
Binding binding1 = new Binding(); binding1.Path = new PropertyPath("Value"); binding1.RelativeSource = RelativeSource.TemplatedParent;
Binding binding2 = new Binding(); binding2.Source = ((Main)App.Current.MainWindow).lbOfferBidFormat; binding2.Path = new PropertyPath("Text"); //SelectedItem
multiBinding.Bindings.Add(binding1); multiBinding.Bindings.Add(binding2);
What are you setting this binding on, are you creating a Style in code using FrameworkElementFactorys? Can you post the rest of the code that makes use of this binding?
The code is below. The multibinding is working fine as I am hitting the custom converter and the value from the combo box is being passed fine but the value from the CellValuePresenter is coming in as UnsetValue. below is the full binding code. When I had this style as a XAML resource and then associate it via code it works fine.
Style style = new Style(typeof(CellValuePresenter)); ControlTemplate ct = new ControlTemplate(typeof(CellValuePresenter));
FrameworkElementFactory fef = new FrameworkElementFactory(typeof(Rectangle));
//Create binding MultiBinding multiBinding = new MultiBinding(); multiBinding.Converter = FindResource("cvpValueChangeConverter") as IMultiValueConverter; //1st binding Binding binding1 = new Binding(); binding1.Path = new PropertyPath("Value"); binding1.RelativeSource = RelativeSource.TemplatedParent;
//2n biding Binding binding2 = new Binding(); binding2.Source = ((Main)App.Current.MainWindow).lbOfferBidFormat; binding2.Path = new PropertyPath("Text"); //SelectedItem
Label label = new Label(); label.Foreground = Brushes.Black; label.FontSize = 10d; label.FontFamily = new FontFamily("Tahoma"); label.VerticalAlignment = VerticalAlignment.Center; label.FontStretch = FontStretches.ExtraCondensed;
label.SetBinding(Label.ContentProperty, multiBinding);
VisualBrush visualBrush = new VisualBrush(label);
fef.SetValue(Rectangle.FillProperty, visualBrush);
ct.VisualTree = fef;
style.Setters.Add(new Setter(Control.TemplateProperty, ct));
The reason this doesn't work is because VisualBrush is not a FrameworkElement so the Label doesn't have a TemplatedParent. When they are parsing the xaml they probably do some special fixup to make it work.
If you can't leave the definition of the style in xaml you will have to change the structure of the template so that you can use nothing but FrameworkElementFactorys so that the element chain isn't broken.
hi joe, you can help me to convert my xaml to code behin too?my xaml is:
<StackPanel x:Name="Stack"> <TextBox Visibility="Visible" x:Name="TextWithUrl" TextWrapping="Wrap" VerticalScrollBarVisibility="Hidden" AcceptsReturn="True" MouseLeave="Change_LeaveTextbox"/> <RichTextBox Visibility="Visible" x:Name="TextLinkUrl" IsReadOnly="True" IsDocumentEnabled="True" local:RTBNavigationService.Content="{Binding Text, ElementName=TextWithUrl}" PreviewMouseLeftButtonDown ="TextLinkUrl_MouseLeftButtonDown" > </RichTextBox></StackPanel>
and works perfectly
my code behin is:
public partial class MainWindow : Window { /// <summary> /// Initializes a new instance of the MainWindow class. /// </summary> public MainWindow() { InitializeComponent(); Closing += (s, e) => ViewModelLocator.Cleanup(); CreateItems(); }
public void Change_LeaveTextbox(object sender, RoutedEventArgs e) { mytry.Content = "adios"; CreateBinding(); if (TextWithUrl.Visibility == Visibility.Visible) { TextWithUrl.Visibility = Visibility.Hidden; TextLinkUrl.Visibility = Visibility.Visible; } }
public void TextLinkUrl_MouseLeftButtonDown(object sender, RoutedEventArgs e) {
mytry.Content = "hola"; if (!Keyboard.IsKeyDown(Key.LeftCtrl)) { if (TextLinkUrl.Visibility == Visibility.Visible) { TextWithUrl.Visibility = Visibility.Visible; TextLinkUrl.Visibility = Visibility.Hidden; } } }
private void CreateItems() { CreateTextBox(); CreateRichTextBox(); //CreateBinding(); }
private void CreateBinding() // FOR BINDING TEXTBOX WITH RICHTEXTBOX { //MultiBinding Binding = new MultiBinding(); //Binding.Converter = FindResource("txtInputData") as IMultiValueConverter; Binding binding1 = new Binding("txtInputData"); binding1.Path = new PropertyPath("Text"); binding1.RelativeSource = RelativeSource.TemplatedParent; }
private void CreateTextBox() // TEXT FOR COPUY OF RICHTEXTBOX { TextBox txtInputData = new TextBox(); //txtInputData.Visibility = Visibility.Hidden; txtInputData.Name = "TextWithUrl"; txtInputData.TextWrapping = TextWrapping.Wrap; txtInputData.VerticalScrollBarVisibility = ScrollBarVisibility.Hidden; txtInputData.AcceptsReturn = true; txtInputData.MouseLeave += new MouseEventHandler(Change_LeaveTextbox); Stack.Children.Add(txtInputData); }
private void CreateRichTextBox() //TEXT COPY OF TEXTBOX { RichTextBox txtOutPutData = new RichTextBox(); txtOutPutData.Visibility = Visibility.Visible; txtOutPutData.Name = "TextLinkUrl"; txtOutPutData.IsReadOnly = true; txtOutPutData.IsDocumentEnabled = true; txtOutPutData.SetBinding(RichTextBox.DataContextProperty, "Binding"); txtOutPutData.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(TextLinkUrl_MouseLeftButtonDown); Stack.Children.Add(txtOutPutData); } }
Thank you very much for your help