wpf - Binding properties to an array code behing - c#

I have to create many controls on runtime and i need to bind to an array, but they doesn't bind.
In the code we can assume that I get 3 nameplates, but when I type data into or select an item they don't set it in the property
View
Grid grid = new Grid();
int top = 10;
int position = 0;
foreach (NameplateModel nameplate in _nameplateList)
{
Label lbl = new Label();
lbl.Content = nameplate.FieldName;
lbl.HorizontalAlignment = HorizontalAlignment.Left;
lbl.VerticalAlignment = VerticalAlignment.Top;
lbl.Margin = new Thickness(0, top, 0, 0);
grid.Children.Add(lbl);
if (nameplate.LookupValue !=null && nameplate.LookupValue.Count() > 0)
{
ComboBox cbo = new ComboBox();
cbo.ItemsSource = nameplate.LookupValue;
Binding b = new Binding();
b.Source = DataContext;
b.Path = new PropertyPath("TextValues[0]");
b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
b.Mode = BindingMode.TwoWay;
cbo.SetBinding(ComboBox.TextProperty,b);
if (!nameplate.LimitToList)
{
cbo.IsEditable = true;
}
cbo.HorizontalAlignment = HorizontalAlignment.Left;
cbo.Margin = new Thickness(98,top,0,0);
cbo.Width = 174;
cbo.VerticalAlignment = VerticalAlignment.Top;
grid.Children.Add(cbo);
}
else
{
TextBox txt = new TextBox();
Binding b = new Binding();
b.Source = DataContext;
b.Path = new PropertyPath(string.Format("TextValues[{0}]", position));
b.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
b.Mode = BindingMode.TwoWay;
txt.SetBinding(TextBox.TextProperty, b);
txt.HorizontalAlignment = HorizontalAlignment.Left;
txt.VerticalAlignment = VerticalAlignment.Top;
txt.Width = 174;
txt.Margin = new Thickness(98, top, 0, 0);
grid.Children.Add(txt);
}
top = top + 29;
position++;
}
scvNameplate.Content = grid;
and my ViewModel
public string[] TextValues
{
get
{
return _textValues ?? (_textValues = new string[3]);
}
set
{
_textValues = value;
OnPropertyChanged("TextValues");
}
}
NameplateModel
public class NameplateModel
{
#region Fields
string _fieldName;
string _lookupCode;
string[] _lookupValue;
bool _limitToList;
#endregion
#region Properties
public string FieldName
{
get
{
return _fieldName;
}
set
{
_fieldName = value;
}
}
public string LookupCode
{
get
{
return _lookupCode;
}
set
{
_lookupCode = value;
}
}
public string[] LookupValue
{
get
{
return _lookupValue;
}
set
{
_lookupValue = value;
}
}
public bool LimitToList
{
get
{
return _limitToList;
}
set
{
_limitToList = value;
}
}
#endregion
}

I got more than I was expecting, First I remove all the code behind and putted in Xaml on the ItemsControl
View
<ItemsControl ItemsSource="{Binding NameplateList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Content="{Binding FieldName}" Margin="0,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Row="0" Grid.Column="0"/>
<ComboBox Text="{Binding TextValue, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding LookupValue}" IsEditable="{Binding LimitToList}" Margin="0,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="174" Grid.Row="0" Grid.Column="1" Visibility="{Binding IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}"/>
<TextBox Text="{Binding TextValue}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="174" Margin="0,0,0,0" Visibility="{Binding IsVisibleText, Converter={StaticResource BooleanToVisibilityConverter}}" Grid.Row="0" Grid.Column="1"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
and then just need to add the string TextValue property to take the value I need into the NameplateModel instead of having a TextValue[] on the viewModel
Now it works perfectly, Thanks #BradleyDotNET

Related

How to make ListBox show different Elements (which are in a List) in wpf

Suppose I have a list which contains some elements and texts:
public MainWindow()
{
InitializeComponent();
TextBlock t = new TextBlock();
t.Text = "Hello World!";
Ellipse e = new Ellipse();
e.Width = 100;
e.Height = 100;
e.Fill = new SolidColorBrush(Colors.Yellow);
Rectangle r = new Rectangle();
r.Width = 70;
r.Height = 40;
r.Fill = new SolidColorBrush(Colors.Blue);
List<UIElementItem> items = new List<UIElementItem>();
items.Add(new UIElementItem() { uiElement = t, Text = "This is a TextBlock: " });
items.Add(new UIElementItem() { uiElement = e, Text = "This is an Ellipse: " });
items.Add(new UIElementItem() { uiElement = r, Text = "This is a Rectangle: " });
lbListBox.ItemsSource = items;
}
}
public class UIElementItem
{
public UIElement uiElement { get; set; }
public string Text { get; set; }
}
This is the ListBox in XAML:
<ListBox Name="lbListBox" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,2" Orientation="Horizontal">
<TextBlock Text="{Binding Text}"/>
<??? = "{Binding uiElement}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I want to make the ListBox show the texts and the elements.
The TextBlock Text="{Binding Text}" will show the text but how to show the element? How to bind?
You could use a ContentPresenter
<ContentPresenter Content="{Binding uiElement}" />
This would show the UI Elements. The complete ItemTemplate would look like
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,2" Orientation="Horizontal">
<TextBlock Text="{Binding Text}"/>
<ContentPresenter Content="{Binding uiElement}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>

UWP Printing Long Datagrid that need to extend to multiple pages

I am making an accounting program using ( uwp , c#, MySQL ), I want to know when printing the reports if the datagrid is long how to extend the rest to new pages so that all report will be printed on multiple pages.
i used printhelp.cs that is in the printing sample: https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/Printing , but it printed the datagrid only on one page and didn't extend the rest to more pages.
UWP XAML:
<Grid>
<controls:DataGrid Grid.Row="2" Grid.RowSpan="5" Grid.ColumnSpan="2"
x:Name="TextContent"
Foreground="Black"
Background="White"
ItemsSource="{x:Bind SelectSOA()}"
AutoGenerateColumns="False"
GridLinesVisibility="Horizontal">
<controls:DataGrid.Columns>
<controls:DataGridTextColumn Header="ID" Binding="{Binding ID}" />
<controls:DataGridTextColumn Header="Account" Binding="{Binding Principal}" />
<controls:DataGridTextColumn Header="Balance" Binding="{Binding Client}" />
</controls:DataGrid.Columns>
<RichTextBlockOverflow x:Name="FirstLinkedContainer" OverflowContentTarget="{Binding ElementName=ContinuationPageLinkedContainer}" Grid.Row="2" Grid.Column="0"/>
<RichTextBlockOverflow x:Name="ContinuationPageLinkedContainer" Grid.Row="3" Grid.ColumnSpan="2"/>
</Grid>
i expect when printing if the Datagrid is long to extend to next page. but it only prints the first page and does not extend the rest to new pages.
You could use the Print Helper class to print the DataGrid, but you still need to manually paging your data in code-behind.
Please see the Windows Community Toolkit PrintHelper sample to learn how to use this class to print the XAML control.
According to that sample, I do a little changes to make a simple code sample for your reference:
<Grid>
<Grid x:Name="RootGrid"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid x:Name="Container"
Grid.RowSpan="2"
Opacity="0" />
<Grid x:Name="CustomPrintContainer"
Opacity="0" />
<Grid x:Name="DirectPrintContainer">
<Grid x:Name="PrintableContent">
<Grid x:Name="XamlRoot" />
</Grid>
</Grid>
</Grid>
<Button Content="Print" Click="Button_Click" VerticalAlignment="Bottom"></Button>
</Grid>
public List<Person> Persons { get; set; }
public MainPage()
{
this.InitializeComponent();
Persons = new List<Person>();
for (int i = 0; i < 100; i++)
{
Persons.Add(new Person
{
PersonId = i,
FirstName = "FirstName" + i,
LastName = "LastName" + i,
Position = "Network Administrator " + i
});
}
}
private PrintHelper _printHelper;
private async void Button_Click(object sender, RoutedEventArgs e)
{
_printHelper = new PrintHelper(CustomPrintContainer);
var pageNumber = 0;
for (int i = 0; i < Persons.Count; i = i + 10)
{
var grid = new Grid();
grid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) });
grid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
// Static header
var header = new TextBlock { Text = "Custom Print", Margin = new Thickness(0, 0, 0, 20) };
Grid.SetRow(header, 0);
grid.Children.Add(header);
// Main content with layout from data template
var dataGrid = new DataGrid();
dataGrid.AutoGenerateColumns = true;
dataGrid.ItemsSource = Persons.Skip(i).Take(10);
Grid.SetRow(dataGrid, 1);
grid.Children.Add(dataGrid);
// Footer with page number
pageNumber++;
var footer = new TextBlock { Text = string.Format("page {0}", pageNumber), Margin = new Thickness(0, 20, 0, 0) };
Grid.SetRow(footer, 2);
grid.Children.Add(footer);
_printHelper.AddFrameworkElementToPrint(grid);
}
_printHelper.OnPrintCanceled += _printHelper_OnPrintCanceled;
_printHelper.OnPrintFailed += _printHelper_OnPrintFailed;
_printHelper.OnPrintSucceeded += _printHelper_OnPrintSucceeded;
var printHelperOptions = new PrintHelperOptions(false);
printHelperOptions.Orientation = Windows.Graphics.Printing.PrintOrientation.Default;
printHelperOptions.AddDisplayOption(StandardPrintTaskOptions.Orientation);
await _printHelper.ShowPrintUIAsync("print sample", printHelperOptions);
}
public class Person
{
public int PersonId { get; set; }
public int DepartmentId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Position { get; set; }
}

Add Button to ForEach loop

I have a foreach loop that lists a bunch of websites. I would like the ability to add a button to next to each of these websites.
e.g.
google.com X //X represents button
facebook.com X
I don't think adding a stackpanel is the way to go as I want to add it next to the textblock being created in this for loop.
public void WebsiteList(string[] blocked_sites)
{
Button removewebsite = new Button();
numofsites = blocked_sites.Length;
website.Margin = new Thickness(57, 75, 10, 20);
website.Width = 300;
removewebsite.Width = 20;
removewebsite.Height = 20;
removewebsite.Foreground = Brushes.Red;
removewebsite.Content = "X";
removewebsite.Background = Brushes.Transparent;
website.Foreground = Brushes.White;
website.TextWrapping = TextWrapping.Wrap;
website.FontSize = 13;
foreach (string Site in blocked_sites)
{
website.Inlines.Add(new Run("• "));
string editedSite = Site.Replace("*://*.", "").Replace("*://*", "").Replace("*://", "").Replace("/*", "");
website.Inlines.Add(new Run(editedSite));
website.Inlines.Add(new LineBreak());
removewebsite.Name = "test";
//HERE IS WHERE I WANT TO ADD THE BUTTON ON THE END
}
}
I've tried adding a stackpanel using stackpanel.children.Add(removewebsite) but it's not lining up with the textblocks. I think I'm just lacking sufficient knowledge in the most suitable way to go about it, would love to be pointed in the right direction.
Use an ItemsControl and set or bind its ItemsSource property to the modified string[]:
public void WebsiteList(string[] blocked_sites)
{
numofsites = blocked_sites.Length;
string[] s = new string[numofsites];
for (int i = 0; i < numofsites; ++i)
{
s[i] = string.Format("• {0}{1}", blocked_sites[i].Replace("*://*.", "").Replace("*://*", "").Replace("*://", "").Replace("/*", ""),
Environment.NewLine);
}
ic.ItemsSource = s;
}
XAML:
<ItemsControl x:Name="ic">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding}" Foreground="White" TextWrapping="Wrap" FontSize="13" Margin="57, 75, 10, 20" Width="300" />
<Button Content="X" Foreground="Red" Width="20" Height="30" VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Showing canvas children in listbox

I'm new here so please excuse my if I missed to add something needed to answer my question.
So heres my question:
I am trying to add shapes to a canvas while also wanting to show a list of them in a listbox, to make them changeable (size,position, etc.). I am using WPF. Is there a way to do so?
And if it doesnt bother you: Is there maybe a question or website or whatever about how to dynamically draw shapes(circle,ellipse,rect, etc.) with mouse events?
I hope you can help me. Thanks in advance.
Edit:
Given the fact that I have:
public partial class MainWindow : Window
{
public ObservableCollection<string> Baselist = new ObservableCollection<string>();
public ObservableCollection<string> Crystallist = new ObservableCollection<string>();
public ObservableCollection<Shape> Shapelist = new ObservableCollection<Shape>();
public MainWindow()
{
this.ResizeMode = System.Windows.ResizeMode.CanMinimize;
InitializeComponent();
InitializeLists(Baseforms,CrystalGroups);
}
private void InitializeLists(ComboBox Baseforms, ComboBox CrystalGroups)
{
Baseforms.ItemsSource = Baselist;
CrystalGroups.ItemsSource = Crystallist;
Shape Circle = new Ellipse();
Circle.Stroke = System.Windows.Media.Brushes.Black;
Circle.Fill = System.Windows.Media.Brushes.DarkBlue;
Circle.HorizontalAlignment = HorizontalAlignment.Left;
Circle.VerticalAlignment = VerticalAlignment.Center;
Circle.Width = 50;
Circle.Height = 50;
Shapelist.Add(Circle);
}
How can I use an ItemsControl to show the shapes in Shapelist in an canvas while also listing them in a Listbox?
Hope this makes the question less broad.
Please try the next solution:
Updated version (xaml and code behind)
DetailsList list view - presents detailed data based on ShapeDataPresentation class (supports multi-select). Shows data by data template named ShapeDataPresentationDataTemplate.
ShapesPresentor items control - presents shapes on canvas (doesn't support multi-select only one can be selected).
ListView XAML code ("This" is the name of the ListView containing window)
<Window x:Class="ListViewWithCanvasPanel.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:listViewWithCanvasPanel="clr-namespace:ListViewWithCanvasPanel"
Title="MainWindow" Height="350" Width="525" x:Name="This" ResizeMode="CanResize">
<Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2.5*"></ColumnDefinition>
<ColumnDefinition Width="4*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<ListView x:Name="DetailsList" Panel.ZIndex="999" Grid.Column="0" ItemsSource="{Binding ElementName=This, Path=Shapes}" SelectionMode="Extended" SelectionChanged="Selector_OnSelectionChanged">
<ListView.Resources>
<DataTemplate x:Key="ShapeDataPresentationDataTemplate" DataType="listViewWithCanvasPanel:ShapeDataPresentation">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Name, StringFormat={}{0:N0}%}"></TextBlock>
<TextBlock Grid.Column="1">
<Run Text="W:"></Run>
<Run Text="{Binding OriginalRectAroundShape.Width}"></Run>
</TextBlock>
<TextBlock Grid.Column="2">
<Run Text="H:"></Run>
<Run Text="{Binding OriginalRectAroundShape.Height}"></Run>
</TextBlock>
</Grid>
</DataTemplate>
</ListView.Resources>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate DataType="Shape">
<ContentControl Content="{Binding Tag}" ContentTemplate="{StaticResource ShapeDataPresentationDataTemplate}"></ContentControl>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
<GridSplitter Grid.Column="0" Width="3" Background="Blue" Panel.ZIndex="999"
VerticalAlignment="Stretch" HorizontalAlignment="Right" Margin="0"/>
<ItemsControl Grid.Column="1" x:Name="ShapesPresentor" ItemsSource="{Binding ElementName=This, Path=Shapes}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
MouseDown="UIElement_OnMouseDown">
<!--<ListView.Resources>
<ControlTemplate x:Key="SelectedTemplate" TargetType="ListViewItem">
<ContentControl Content="{Binding }"></ContentControl>
</ControlTemplate>
</ListView.Resources>-->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="White" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!--<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true" />
<Condition Property="Selector.IsSelectionActive" Value="true" />
</MultiTrigger.Conditions>
<Setter Property="Template" Value="{StaticResource SelectedTemplate}" />
</MultiTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>-->
</ItemsControl>
</Grid>
<StackPanel VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Orientation="Horizontal">
<ComboBox x:Name="Baseforms"></ComboBox>
<ComboBox x:Name="CrystalGroups"></ComboBox>
</StackPanel>
</Grid>
Code behind (updated)
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public static readonly DependencyProperty ShapesProperty = DependencyProperty.Register(
"Shapes", typeof (ObservableCollection<Shape>), typeof (MainWindow),
new PropertyMetadata(default(ObservableCollection<Shape>)));
public ObservableCollection<Shape> Shapes
{
get { return (ObservableCollection<Shape>) GetValue(ShapesProperty); }
set { SetValue(ShapesProperty, value); }
}
public ObservableCollection<string> Baselist = new ObservableCollection<string> {"a", "b", "c"};
public ObservableCollection<string> Crystallist = new ObservableCollection<string>{"aa", "bb", "cc"};
public ObservableCollection<Shape> Shapelist = new ObservableCollection<Shape>();
private SolidColorBrush _originalColorBrush = Brushes.Tomato;
private SolidColorBrush _selectedColorBrush;
private double _diameter;
public MainWindow()
{
_diameter = 50d;
this.ResizeMode = System.Windows.ResizeMode.CanMinimize;
Shapes = new ObservableCollection<Shape>();
InitializeComponent();
InitializeLists(Baseforms, CrystalGroups);
}
private void InitializeLists(ComboBox Baseforms, ComboBox CrystalGroups)
{
Baseforms.ItemsSource = Baselist;
CrystalGroups.ItemsSource = Crystallist;
Shape Circle = new Ellipse();
Circle.Stroke = System.Windows.Media.Brushes.Black;
Circle.Fill = System.Windows.Media.Brushes.DarkBlue;
Circle.HorizontalAlignment = HorizontalAlignment.Left;
Circle.VerticalAlignment = VerticalAlignment.Center;
Circle.Width = 50;
Circle.Height = 50;
Shapelist.Add(Circle);
}
private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e)
{
var inputElement = sender as IInputElement;
if (inputElement == null) return;
var point = e.GetPosition(inputElement);
Shape shape = new Ellipse
{
Stroke = Brushes.Black,
Fill = _originalColorBrush,
Width = _diameter,
Height = _diameter
};
var byX = point.X - _diameter / 2d;
var byY = point.Y - _diameter / 2d;
var existingShape = Shapes.FirstOrDefault(shapeToCheck =>
{
var data = shapeToCheck.Tag as ShapeDataPresentation;
if (data == null) return false;
var res = data.OriginalRectAroundShape.IntersectsWith(new Rect(point,point));
return res;
});
if (existingShape == null)
{
var shapeDataPresentation = new ShapeDataPresentation { Name = string.Format("Ox:{0}, Oy:{1}", point.X.ToString("##.###"), point.Y.ToString("##.###")), OriginalRectAroundShape = new Rect(new Point(byX, byY), new Size(_diameter, _diameter)) };
shape.Tag = shapeDataPresentation;
shape.ToolTip = new ToolTip{Content = shapeDataPresentation.Name};
var translateTransform = new TranslateTransform(byX, byY);
shape.RenderTransform = translateTransform;
Shapes.Add(shape);
}
else
{
if (DetailsList.SelectedItems.Contains(existingShape) == false)
{
DetailsList.SelectedItems.Clear();
DetailsList.SelectedItems.Add(existingShape);
}
}
}
private void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var currentSelected = e.AddedItems.OfType<Shape>().ToList();
var prevSelected = e.RemovedItems.OfType<Shape>().ToList();
if (currentSelected.Count > 0)
{
currentSelected.ForEach(shape =>
{
_selectedColorBrush = Brushes.CadetBlue;
shape.Fill = _selectedColorBrush;
});
}
if (prevSelected.Count > 0)
{
prevSelected.ForEach(shape =>
{
shape.Fill = _originalColorBrush;
});
}
}
}
public class ShapeDataPresentation
{
public string Name { get; set; }
public Rect OriginalRectAroundShape { get; set; }
}
How it is looks like
Summary:
Here you can create item by mouse click on canvas, mouse down handled
in code (UIElement_OnMouseDown).
Allowed selection and multi-selection, each time you make selection it will be handled in code (Selector_OnSelectionChanged).
But it is better to use the MVVM based approach to work in wpf.
Regards.

Custom UserControl not showing up in ListBox

I have a problem displaying custom UserControls in my ListBox programmatically. I just can't seem to figure out what is wrong. The list-item shows up without image or text.
My project consists of:
MainWindow.xaml
MainWindow.xaml.cs
cvMenuItem.xaml
cvMenuItem.xaml.cs
Code of MainWindow.xaml.cs
private void cvMenuItem_MouseLeftButtonUp_1(object sender, MouseButtonEventArgs e)
{
lstContacts.Items.Clear();
cvMenuItem test = new cvMenuItem("test",
Environment.GetEnvironmentVariable("USERPROFILE") + #"\Downloads\images.jpg");
lstContacts.Items.Add(test);
}
Code of cvMenuItem.xaml.cs
public partial class cvMenuItem : UserControl
{
public cvMenuItem()
{
InitializeComponent();
}
public cvMenuItem(string text, string Logo)
{
this.Height = 50;
this.Width = 186;
txtService = new TextBlock() { Width = 100, Height = 50 };
imgLogo = new Image() { Width = 50, Height = 50 };
//Just found out, adding the objects as childeren partially works
this.AddChild(imgLogo);
//But I can't add txtService as Childeren
//this.AddChild(txtService);
this.Services = text;
this.Logo = Logo;
}
public string Services
{
get{ return txtService.Text.ToString() }
set
{
txtService.Text = value;
}
}
public string Logo
{
get{ return imgLogo.Source.ToString(); }
set
{
var uriSource = new Uri(value);
imgLogo.Source = new BitmapImage(uriSource);
}
}
My cvMenuItem.xaml.cs
<UserControl x:Class="WpfApplication1.cvMenuItem"
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"
mc:Ignorable="d" Height="50" Width="186">
<Grid Width="186" VerticalAlignment="Top">
<Image Name="imgLogo" Height="50" Width="50" HorizontalAlignment="Left" VerticalAlignment="Top" OpacityMask="{DynamicResource {x:Static SystemColors.ActiveCaptionTextBrushKey}}" />
<TextBlock Name="txtService" HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Bottom" Height="18" Width="121" Margin="70,0,0,18" RenderTransformOrigin="0.499,1.932"/>
</Grid>
</UserControl>
First of all you need to call InitializeComponent in the custom constructor you have added, as that is needed to process the XAML properly. Otherwise all the controls you add in the XAML will be null when running the application.
Additionally it makes no sense to create the TextBlock and Image again in the code-behind. You just have to use the ones created in the XAML.
So to get it working, change the code in the constructor to the following:
public cvMenuItem(string text, string Logo)
{
InitializeComponent();
this.Height = 50;
this.Width = 186;
this.Services = text;
this.Logo = Logo;
}

Categories

Resources