/ / प्रोग्रामेटिक रूप से डब्ल्यूपीएफ फॉर्म में नियंत्रण जोड़ें - डब्ल्यूपीएफ, गतिशील, नियंत्रण

प्रोग्रामेटिक रूप से WPF फॉर्म में नियंत्रण जोड़ें - wpf, डायनामिक, कंट्रोल

मैं UserControl में नियंत्रण जोड़ने की कोशिश कर रहा हूंगतिशील रूप से (प्रोग्रामिक रूप से)। मुझे अपने बिजनेस लेयर (डेटाबेस से पुनर्प्राप्त) से ऑब्जेक्ट्स की एक सामान्य सूची मिलती है, और प्रत्येक ऑब्जेक्ट के लिए, मैं wpf UserControl में एक लेबल और टेक्स्टबॉक्स जोड़ना चाहता हूं और अच्छी दिखने के लिए स्थिति और चौड़ाई सेट करना चाहता हूं, और उम्मीद है डब्ल्यूपीएफ सत्यापन क्षमताओं का लाभ उठाएं। यह ऐसा कुछ है जो विंडोज़ फॉर्म प्रोग्रामिंग में आसान होगा लेकिन मैं डब्ल्यूपीएफ के लिए नया हूं। मैं यह कैसे कर सकता हूं (प्रश्नों के लिए टिप्पणियां देखें) कहें कि यह मेरी वस्तु है:

public class Field {
public string Name { get; set; }
public int Length { get; set; }
public bool Required { get; set; }
}

फिर मेरे wpf UserControl में, मैं प्रत्येक ऑब्जेक्ट के लिए लेबल और टेक्स्टबॉक्स बनाने की कोशिश कर रहा हूं:

public void createControls() {
List<Field> fields = businessObj.getFields();

Label label = null;
TextBox textbox = null;

foreach (Field field in fields) {
label = new Label();
// HOW TO set text, x and y (margin), width, validation based upon object?
// i have tried this without luck:
// Binding b = new Binding("Name");
// BindingOperations.SetBinding(label, Label.ContentProperty, b);
MyGrid.Children.Add(label);

textbox = new TextBox();
// ???
MyGrid.Children.Add(textbox);
}
// databind?
this.DataContext = fields;
}

उत्तर:

उत्तर № 1 के लिए 21

ठीक है, दूसरी बार का आकर्षण है। आपके लेआउट स्क्रीनशॉट के आधार पर, मैं तुरंत अनुमान लगा सकता हूं कि आपको जो चाहिए वह एक है WrapPanel, एक लेआउट पैनल जो आइटम को एक किनारे तक पहुंचने तक भरने की अनुमति देता है, जिस बिंदु पर शेष आइटम अगली पंक्ति में प्रवाहित होते हैं। लेकिन आप अभी भी एक का उपयोग करना चाहते हैं ItemsControl ताकि आप डेटा-बाइंडिंग और डायनेमिक जेनरेशन के सभी लाभ प्राप्त कर सकें। तो इसके लिए हम उपयोग करने जा रहे हैं ItemsControl.ItemsPanel संपत्ति, जो हमें उस पैनल को निर्दिष्ट करने की अनुमति देती है जिसमें आइटम रखे जाएंगे। आइए फिर से कोड-बैक से शुरू करें:

public partial class Window1 : Window
{
public ObservableCollection<Field> Fields { get; set; }

public Window1()
{
InitializeComponent();

Fields = new ObservableCollection<Field>();
Fields.Add(new Field() { Name = "Username", Length = 100, Required = true });
Fields.Add(new Field() { Name = "Password", Length = 80, Required = true });
Fields.Add(new Field() { Name = "City", Length = 100, Required = false });
Fields.Add(new Field() { Name = "State", Length = 40, Required = false });
Fields.Add(new Field() { Name = "Zipcode", Length = 60, Required = false });

FieldsListBox.ItemsSource = Fields;
}
}

public class Field
{
public string Name { get; set; }
public int Length { get; set; }
public bool Required { get; set; }
}

यहां बहुत कुछ नहीं बदला है, लेकिन मैंने आपके उदाहरण से बेहतर मिलान करने के लिए नमूना फ़ील्ड संपादित किए हैं। अब देखते हैं कि जादू कहां होता है- XAML के लिए Window:

<Window x:Class="DataBoundFields.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DataBoundFields"
Title="Window1" Height="200" Width="300">
<Window.Resources>
<local:BoolToVisibilityConverter x:Key="BoolToVisConverter"/>
</Window.Resources>
<Grid>
<ListBox x:Name="FieldsListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label Content="{Binding Name}" VerticalAlignment="Center"/>
<TextBox Width="{Binding Length}" Margin="5,0,0,0"/>
<Label Content="*" Visibility="{Binding Required, Converter={StaticResource BoolToVisConverter}}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"
Height="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=ActualHeight}"
Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=ActualWidth}"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Grid>

सबसे पहले, आप देखेंगे कि ItemTemplate थोड़ा बदल गया है।लेबल अभी भी नाम संपत्ति के लिए बाध्य है, लेकिन अब टेक्स्टबॉक्स चौड़ाई लंबाई संपत्ति से जुड़ी है (इसलिए आपके पास अलग-अलग लंबाई के टेक्स्टबॉक्स हो सकते हैं)। इसके अलावा, मैंने किसी भी क्षेत्र में एक "*" जोड़ा है जिसकी आवश्यकता है, एक सरलीकृत . का उपयोग करके BoolToVisibilityConverter (जिसे आप कहीं भी कोड पा सकते हैं, और मैं यहां पोस्ट नहीं करूंगा)।

ध्यान देने वाली मुख्य बात a . का उपयोग है WrapPanel में ItemsPanel हमारे की संपत्ति ListBox. यह बताता है ListBox कि इससे उत्पन्न होने वाली किसी भी वस्तु को धकेलने की आवश्यकता हैएक क्षैतिज लिपटे लेआउट में (यह आपके स्क्रीनशॉट से मेल खाता है)। जो चीज इस काम को और भी बेहतर बनाती है वह है पैनल पर बाध्यकारी ऊंचाई और चौड़ाई- यह क्या कहता है, "इस पैनल को मेरी पैरेंट विंडो के समान आकार दें।" इसका मतलब है कि जब मैं आकार बदलता हूं Window, द WrapPanel अपने आकार को तदनुसार समायोजित करता है, जिसके परिणामस्वरूप वस्तुओं के लिए एक बेहतर लेआउट होता है। यहां दो स्क्रीनशॉट इसे प्रदर्शित करते हैं:

वैकल्पिक पाठ http://img156.imageshack.us/img156/6849/wrappanelfields.png

वैकल्पिक पाठ http://img12.imageshack.us/img12/2426/wrappanelfields2.png


जवाब के लिए 15 № 2

इस तरह के नियंत्रण जोड़ने की अनुशंसा नहीं की जाती है।डब्ल्यूपीएफ में आप जो आदर्श रूप से करते हैं वह एक लिस्टबॉक्स (या आइटम्स कंट्रोल) डालना है और अपने बिजनेस ऑब्जेक्ट संग्रह को आइटम्स कंट्रोल के रूप में बांधना है। आइटम्ससोर्स प्रॉपर्टी। अब अपने डेटाऑब्जेक्ट प्रकार के लिए एक्सएएमएल में डेटा टेम्पलेट को परिभाषित करें और आप जाने के लिए अच्छे हैं, यह डब्ल्यूपीएफ का जादू है।

लोग Winforms पृष्ठभूमि से आते हैं जिस तरह से आपने वर्णन किया है और जो wpf में सही तरीका नहीं है।


उत्तर के लिए 7 № 3

मैं चार्ली और जोबी के उत्तरों को सुनूंगा, लेकिन सीधे प्रश्न का उत्तर देने के लिए ... (नियंत्रण कैसे जोड़ें और उन्हें मैन्युअल रूप से कैसे रखें।)

का उपयोग Canvas नियंत्रण, बजाय a Grid. कैनवस नियंत्रण को अनंत मात्रा में स्थान देते हैं, और आपको उन्हें मैन्युअल रूप से रखने की अनुमति देते हैं। यह स्थिति का ट्रैक रखने के लिए संलग्न गुणों का उपयोग करता है। कोड में, यह ऐसा दिखेगा:

var tb = new TextBox();
myCanvas.Children.Add(tb);
tb.Width = 100;
Canvas.SetLeft(tb, 50);
Canvas.SetTop(tb, 20);

एक्सएएमएल में...

<Canvas>
<TextBox Width="100" Canvas.Left="50" Canvas.Top="20" />
</Canvas>

आप उन्हें दाएं और नीचे के किनारों के सापेक्ष भी रख सकते हैं। ऊपर और नीचे दोनों को निर्दिष्ट करने से कैनवास के साथ नियंत्रण लंबवत रूप से आकार बदल जाएगा। इसी तरह लेफ्ट और राइट के लिए।