2010-01-18 9 views
8

WPF का उपयोग करके एक सूची बॉक्स में इनलाइन संपादन टेक्स्टब्लॉक, मेरे पास ListBoxDataTemplate के साथ नियंत्रण है। प्रासंगिक XAML कोड नीचे दिखाया गया है:डेटा टेम्पलेट (WPF)

<ListBox Name="_todoList" Grid.Row="1" BorderThickness="2" 
    Drop="todoList_Drop" AllowDrop="True" 
    HorizontalContentAlignment="Stretch" 
    ScrollViewer.HorizontalScrollBarVisibility="Disabled"     
    AlternationCount="2"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <Grid Margin="4"> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="Auto" /> 
        <ColumnDefinition Width="*" /> 
       </Grid.ColumnDefinitions> 
       <CheckBox Grid.Column="0" Checked="CheckBox_Check" /> 
       <TextBlock Name="descriptionBlock" 
          Grid.Column="1" 
          Text="{Binding Description}" 
          Cursor="Hand" FontSize="14" 
          ToolTip="{Binding Description}" 
          MouseDown="TextBlock_MouseDown" />      
      </Grid> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

मुझे क्या करना कोशिश कर रहा हूँ एक (डबल) को TextBlock प्रतिक्रिया बनाने के लिए क्लिक करें जो इसे एक TextBox में बदल जाता है है। उपयोगकर्ता विवरण को संपादित कर सकते हैं, और परिवर्तन करने के लिए वापसी या फोकस बदल सकते हैं।

मैं TextBlock के रूप में एक ही स्थिति में एक TextBox तत्व जोड़ और उसके दृश्यता Collapsed बनाने की कोशिश की है, लेकिन मैं उपयोगकर्ता एक TextBlock पर क्लिक किया हो सही TextBox नेविगेट करने के लिए कैसे पता नहीं है। यही है, मुझे पता है कि उपयोगकर्ता ने एक निश्चित TextBlock पर क्लिक किया है, अब जोTextBox क्या मैं दिखाता हूं?

किसी भी मदद की बहुत सराहना की जाएगी,

-Ko9

+0

'प्री' टैग का उपयोग करने और स्पष्ट रूप से एंगल ब्रैकेट से बचने के बजाय, आप XAML को सीधे संपादक में पेस्ट कर सकते हैं और कोड के रूप में प्रारूपित करने के लिए 101010 बटन का उपयोग कर सकते हैं। – itowlson

उत्तर

14

मैंने इन परिस्थितियों में जो किया है, वह एक्सएएमएल पदानुक्रम का उपयोग यह निर्धारित करने के लिए किया जाता है कि कौन सा तत्व दिखाना/छिपाना है। कोड के साथ

<Grid> 
    <TextBlock MouseDown="txtblk_MouseDown" /> 
    <TextBox LostFocus="txtbox_LostFocus" Visibility="Collapsed" /> 
</Grid> 

: की तर्ज पर कुछ

protected void txtblk_MouseDown(object sender, MouseButtonEventArgs e) 
{ 
    TextBox txt = (TextBox)((Grid)((TextBlock)sender).Parent).Children[1]; 
    txt.Visibility = Visibility.Visible; 
    ((TextBlock)sender).Visibility = Visibility.Collapsed; 
} 

protected void txtbox_LostFocus(object sender, RoutedEventArgs e) 
{ 
    TextBlock tb = (TextBlock)((Grid)((TextBox)sender).Parent).Children[0]; 
    tb.Text = ((TextBox)sender).Text; 
    tb.Visibility = Visibility.Visible; 
    ((TextBox)sender).Visibility = Visibility.Collapsed; 
} 

मैं हमेशा इस है कि मैं एक UserControl, मैं अतिरिक्त त्रुटि के लिए से निपटने में जोड़ सकते हैं जो में पुन: उपयोग करने जा रहा हूँ की तरह सामान की बारी है, और गारंटी दें कि Grid में केवल दो आइटम होंगे, और उनमें से आदेश कभी नहीं बदलेगा।

संपादित करें: इसके अतिरिक्त, इसे उपयोगकर्ता नियंत्रण में बदलना आपको प्रत्येक तत्कालता के लिए Text संपत्ति बनाने की अनुमति देता है, ताकि आप ((TextBox)myGrid.Children[1]).Text कास्टिंग के माध्यम से वर्तमान मूल्य के लिए मछली पकड़ने के बिना सीधे पाठ का संदर्भ दे सकें।इससे आपका कोड अधिक कुशल और साफ हो जाएगा। यदि आप इसे UserControl में बनाते हैं, तो आप TextBlock और TextBox तत्वों का नाम भी दे सकते हैं, इसलिए किसी भी कास्टिंग की आवश्यकता नहीं है।

+0

यह अजीब लग सकता है, क्या आप अपना जवाब संपादित कर सकते हैं ... मैंने समय-समय पर क्लिक किया, फिर मेरा वोट हटा दिया, क्योंकि मुझे यकीन नहीं था कि यह मेरे बाद क्या था। मैंने फिर एक बार फिर से मतदान करने की कोशिश की क्योंकि मुझे वही चाहिए जो मुझे चाहिए और स्टैक ओवरफ्लो का कहना है कि जब तक इसे संपादित नहीं किया जाता तब तक मैं इस पोस्ट पर वोट नहीं दे सकता। इसलिए अनुरोध। चीयर्स, बहुत उपयोगी पोस्ट के रूप में यह निकला। –

4

यह करने के लिए एक ClickEditableTextBlock नियंत्रण है, जो डिफ़ॉल्ट रूप से एक TextBlock के रूप में प्रस्तुत होती है किसी पाठ बॉक्स से पता चलता बनाने के लिए किया जाएगा आदर्श तरीका है जब उपयोगकर्ता क्लिक करता है यह। चूंकि किसी भी दिए गए ClickEditableTextBlock में केवल एक टेक्स्टब्लॉक और एक टेक्स्टबॉक्स है, तो आपके पास मेलिंग समस्या नहीं है। फिर आप अपने DataTemplate में अलग टेक्स्टब्लॉक और टेक्स्टबॉक्स के बजाय एक क्लिकएडेबल टेक्स्टक्लॉक का उपयोग करते हैं।

इसका नियंत्रण में कार्यक्षमता को समाहित करने का साइड लाभ है, इसलिए आप अपने मुख्य विंडो कोड-पीछे संपादन व्यवहार के साथ प्रदूषित नहीं करते हैं, साथ ही आप इसे अन्य टेम्पलेट्स में आसानी से पुन: उपयोग कर सकते हैं।


यह भी बहुत प्रयास की तरह लगता है, तो आप टैग या एक संलग्न संपत्ति का उपयोग कर सकते किसी पाठ बॉक्स के साथ प्रत्येक TextBlock संबद्ध करने के लिए:

<DataTemplate> 
    <StackPanel> 
    <TextBlock Text="whatever" 
       MouseDown="TextBlock_MouseDown" 
       Tag="{Binding ElementName=tb}" /> 
    <TextBox Name="tb" /> 
    </StackPanel> 
</DataTemplate> 

नोट टैग पर {Binding ElementName=tb} के उपयोग का उल्लेख करने के टेक्स्टबॉक्स ने tb नाम दिया।

और में अपने कोड-पीछे:

private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e) 
{ 
    FrameworkElement textBlock = (FrameworkElement)sender; 
    TextBox editBox = (TextBox)(textBlock.Tag); 
    editBox.Text = "Wow!"; // or set visible or whatever 
} 

(बुरा टैग संपत्ति के उपयोग से बचने के लिए, आप एक कस्टम जुड़ी संपत्ति पाठ बॉक्स बाइंडिंग ले जाने के लिए निर्धारित कर सकते हैं, लेकिन मैं नहीं दिखा रहा हूँ संक्षिप्तता के लिए वह।)

11

नाथन व्हीलर के कोड स्निपेट का संदर्भ लें, निम्नलिखित कोड पूरे उपयोगकर्ता नियंत्रण स्रोत हैं जिन्हें मैंने कल कोड किया था। विशेष रूप से, बाध्यकारी मुद्दों को संबोधित किया जाता है। नाथन का कोड पालन करना आसान है, लेकिन डाटाबेस टेक्स्ट के साथ काम करने के लिए कुछ सहायता की आवश्यकता है।

ClickToEditTextboxControl.xaml.cs

public partial class ClickToEditTextboxControl : UserControl 
{ 
    public ClickToEditTextboxControl() 
    { 
     InitializeComponent(); 
    } 

    public string Text 
    { 
     get { return (string)GetValue(TextProperty); } 
     set { SetValue(TextProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty TextProperty = 
     DependencyProperty.Register("Text", typeof(string), typeof(ClickToEditTextboxControl), new UIPropertyMetadata()); 

    private void textBoxName_LostFocus(object sender, RoutedEventArgs e) 
    { 
     var txtBlock = (TextBlock)((Grid)((TextBox)sender).Parent).Children[0]; 

     txtBlock.Visibility = Visibility.Visible; 
     ((TextBox)sender).Visibility = Visibility.Collapsed; 
    } 

    private void textBlockName_MouseDown(object sender, MouseButtonEventArgs e) 
    { 
     var grid = ((Grid) ((TextBlock) sender).Parent); 
     var tbx = (TextBox)grid.Children[1]; 
     ((TextBlock)sender).Visibility = Visibility.Collapsed; 
     tbx.Visibility = Visibility.Visible; 

     this.Dispatcher.BeginInvoke((Action)(() => Keyboard.Focus(tbx)), DispatcherPriority.Render); 
    } 

    private void TextBoxKeyDown(object sender, KeyEventArgs e) 
    { 
     if (e == null) 
      return; 

     if (e.Key == Key.Return) 
     { 
      TextBoxLostFocus(sender, null); 
     } 
    } 
} 

ClickToEditTextboxControl.xaml

<UserControl x:Class="Template.ClickToEditTextboxControl" 
     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" 
     Name="root" 
     d:DesignHeight="30" d:DesignWidth="100"> 
<Grid> 
    <TextBlock Name="textBlockName" Text="{Binding ElementName=root, Path=Text}" VerticalAlignment="Center" MouseDown="textBlockName_MouseDown" /> 
    <TextBox Name="textBoxName" Text="{Binding ElementName=root, Path=Text, UpdateSourceTrigger=PropertyChanged}" Visibility="Collapsed" LostFocus="textBoxName_LostFocus" KeyDown ="TextBoxKeyDown"/> 
</Grid> 
</UserControl> 

और अंत में, आप नीचे के रूप में XAML में इस पर नियंत्रण का उपयोग कर सकते हैं:

<Template1:ClickToEditTextboxControl Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" MinWidth="40" Height="23" /> 

ध्यान दें कि मोड = दोवे, UpdateSourceTrigger = PropertyChanged सेट है। यह बाध्य मूल्य को हर प्रकार में बदलने में सक्षम बनाता है।

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^