ডাব্লুপিএফ: একটি ডায়ালগ / প্রম্পট তৈরি করুন


84

ব্যবহারকারীর ইনপুটটির জন্য আমাকে পাঠ্যবক্স সহ একটি ডায়ালগ / প্রম্পট তৈরি করতে হবে। আমার সমস্যাটি হল, ডায়ালগটি নিশ্চিত হওয়ার পরে পাঠ্যটি কীভাবে পাবেন? সাধারণত আমি এটির জন্য একটি ক্লাস তৈরি করতাম যা কোনও সম্পত্তির পাঠ্য সংরক্ষণ করতে পারে। তবে আমি এক্সএএমএল ব্যবহার করে ডায়ালগটি ডিজাইন করতে চাই। সুতরাং আমি কোনও সম্পত্তিতে টেক্সটবক্সের বিষয়বস্তু সংরক্ষণ করার জন্য এক্সএএমএল কোডটি প্রসারিত করতে চাই - তবে আমার ধারণা বিশুদ্ধ এক্সএএমএল দিয়ে এটি সম্ভব নয়। আমি কী করতে চাই তা বোঝার সর্বোত্তম উপায় কী হবে? এক্সএএমএল থেকে সংজ্ঞায়িত করা যেতে পারে তবে কীভাবে কোনওভাবে ইনপুট ফিরিয়ে দিতে পারে এমন একটি ডায়ালগ কীভাবে তৈরি করবেন? কোন ইঙ্গিত জন্য ধন্যবাদ!

উত্তর:


143

"দায়বদ্ধ" উত্তরটি আমার পক্ষে ডায়ালগটির জন্য একটি ভিউমোডেল তৈরি করার পরামর্শ দেওয়া এবং টেক্সটবক্সে দ্বি-মুখী ডেটাবাইন্ডিং ব্যবহার করা যাতে ভিউমোডেলের কিছু "রেসপন্সটেক্সট" সম্পত্তি থাকে বা কী নেই। এটি করার পক্ষে যথেষ্ট সহজ তবে সম্ভবত ওভারকিল।

ব্যবহারিক উত্তরটি হ'ল কেবলমাত্র আপনার পাঠ্য বাক্সকে একটি এক্স দিতে হবে: নাম যাতে এটি সদস্য হয় এবং পাঠ্যটিকে আপনার কোডের মতো এই শ্রেণীর পিছনে একটি সম্পত্তি হিসাবে প্রকাশ করে:

<!-- Incredibly simplified XAML -->
<Window x:Class="MyDialog">
   <StackPanel>
       <TextBlock Text="Enter some text" />
       <TextBox x:Name="ResponseTextBox" />
       <Button Content="OK" Click="OKButton_Click" />
   </StackPanel>
</Window>

তারপরে আপনার কোডের পিছনে ...

partial class MyDialog : Window {

    public MyDialog() {
        InitializeComponent();
    }

    public string ResponseText {
        get { return ResponseTextBox.Text; }
        set { ResponseTextBox.Text = value; }
    }

    private void OKButton_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        DialogResult = true;
    }
}

তারপরে এটি ব্যবহার করতে ...

var dialog = new MyDialog();
if (dialog.ShowDialog() == true) {
    MessageBox.Show("You said: " + dialog.ResponseText);
}

দেরী জবাবের জন্য আপনাকে অনেক ধন্যবাদ এবং দুঃখিত! আমি প্রথমে আপনাকে দেখানো মত একটি ক্লাস তৈরির পরিবর্তে কোনও ফাইল থেকে এক্সএএমএল লোড করার দিকে খুব বেশি মনোনিবেশ করেছিলাম।
stefan.at.wpf

7
আপনাকে ঠিক আছে বাটন ক্লিক ইভেন্টটি পরিচালনা করতে হবে এবং এটি সেট করতে হবে ial ডায়ালগআরসাল্ট = সত্য; কথোপকথনটি বন্ধ করতে এবং সংলাপ করতে হবে h শো ডায়ালগ () == সত্য।
এরউইন মায়ার

এটি এখনও একটি দুর্দান্ত উত্তর।
tCoe


আমি এখানে দেখতে পাচ্ছি কেবল একটি সমস্যা, এই ডায়ালগটিতে বাটন এবং মিনিমাইজ বোতামটিও রয়েছে .... এই বোতামগুলি অক্ষম করা কি সম্ভব?
আলেকসি টিমোশচেঙ্কো

35

আমি এটিকে ম্যাসেজবক্সের মতো ডাকতে কেবল একটি স্থিতিশীল পদ্ধতি যুক্ত করেছি:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    x:Class="utils.PromptDialog"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    WindowStartupLocation="CenterScreen" 
    SizeToContent="WidthAndHeight"
    MinWidth="300"
    MinHeight="100"
    WindowStyle="SingleBorderWindow"
    ResizeMode="CanMinimize">
<StackPanel Margin="5">
    <TextBlock Name="txtQuestion" Margin="5"/>
    <TextBox Name="txtResponse" Margin="5"/>
    <PasswordBox Name="txtPasswordResponse" />
    <StackPanel Orientation="Horizontal" Margin="5" HorizontalAlignment="Right">
        <Button Content="_Ok" IsDefault="True" Margin="5" Name="btnOk" Click="btnOk_Click" />
        <Button Content="_Cancel" IsCancel="True" Margin="5" Name="btnCancel" Click="btnCancel_Click" />
    </StackPanel>
</StackPanel>
</Window>

এবং পিছনে কোড:

public partial class PromptDialog : Window
{
    public enum InputType
    {
        Text,
        Password
    }

    private InputType _inputType = InputType.Text;

    public PromptDialog(string question, string title, string defaultValue = "", InputType inputType = InputType.Text)
    {
        InitializeComponent();
        this.Loaded += new RoutedEventHandler(PromptDialog_Loaded);
        txtQuestion.Text = question;
        Title = title;
        txtResponse.Text = defaultValue;
        _inputType = inputType;
        if (_inputType == InputType.Password)
            txtResponse.Visibility = Visibility.Collapsed;
        else
            txtPasswordResponse.Visibility = Visibility.Collapsed;
    }

    void PromptDialog_Loaded(object sender, RoutedEventArgs e)
    {
        if (_inputType == InputType.Password)
            txtPasswordResponse.Focus();
        else
            txtResponse.Focus();
    }

    public static string Prompt(string question, string title, string defaultValue = "", InputType inputType = InputType.Text)
    {
        PromptDialog inst = new PromptDialog(question, title, defaultValue, inputType);
        inst.ShowDialog();
        if (inst.DialogResult == true)
            return inst.ResponseText;
        return null;
    }

    public string ResponseText
    {
        get
        {
            if (_inputType == InputType.Password)
                return txtPasswordResponse.Password;
            else
                return txtResponse.Text;
        }
    }

    private void btnOk_Click(object sender, RoutedEventArgs e)
    {
        DialogResult = true;
        Close();
    }

    private void btnCancel_Click(object sender, RoutedEventArgs e)
    {
        Close();
    }
}

সুতরাং আপনি এটি কল করতে পারেন:

string repeatPassword = PromptDialog.Prompt("Repeat password", "Password confirm", inputType: PromptDialog.InputType.Password);

6
MessageBoxস্টাইল স্ট্যাটিক পদ্ধতি প্রয়োগের জন্য +1 । সংক্ষিপ্ত, পুনরায় ব্যবহারযোগ্য কোড!
অ্যারন ব্লেনকুশ

4
"স্থির" শব্দটি দেখামাত্রই আমি অন্যান্য উত্তরগুলি উপেক্ষা করেছি। ধন্যবাদ! :)
ম্যাপলেমলে

16

জোশের দুর্দান্ত উত্তর, তার কাছে সমস্ত কৃতিত্ব, আমি এটিকে কিছুটা হলেও এটিকে পরিবর্তন করেছি:

মাই ডায়ালগ জ্যামল

    <StackPanel Margin="5,5,5,5">
        <TextBlock Name="TitleTextBox" Margin="0,0,0,10" />
        <TextBox Name="InputTextBox" Padding="3,3,3,3" />
        <Grid Margin="0,10,0,0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Button Name="BtnOk" Content="OK" Grid.Column="0" Margin="0,0,5,0" Padding="8" Click="BtnOk_Click" />
            <Button Name="BtnCancel" Content="Cancel" Grid.Column="1" Margin="5,0,0,0" Padding="8" Click="BtnCancel_Click" />
        </Grid>
    </StackPanel>

পিছনে মাই ডায়ালগ কোড

    public MyDialog()
    {
        InitializeComponent();
    }

    public MyDialog(string title,string input)
    {
        InitializeComponent();
        TitleText = title;
        InputText = input;
    }

    public string TitleText
    {
        get { return TitleTextBox.Text; }
        set { TitleTextBox.Text = value; }
    }

    public string InputText
    {
        get { return InputTextBox.Text; }
        set { InputTextBox.Text = value; }
    }

    public bool Canceled { get; set; }

    private void BtnCancel_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        Canceled = true;
        Close();
    }

    private void BtnOk_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        Canceled = false;
        Close();
    }

এবং অন্য কোথাও কল করুন

var dialog = new MyDialog("test", "hello");
dialog.Show();
dialog.Closing += (sender,e) =>
{
    var d = sender as MyDialog;
    if(!d.Canceled)
        MessageBox.Show(d.InputText);
}

আপনার (আপনার গ্রিড সংজ্ঞা xaml তে) 50 * এবং 50 * * এবং * এর সাথে প্রতিস্থাপন করা উচিত কারণ 50 এর কোনও প্রয়োজন নেই
মাফাই

টিপ: WindowStyle="ToolWindow"উইন্ডোতে সেট করা এটি আরও সুন্দর দেখায়। এছাড়াও WindowStartupLocation="CenterOwner"এবং dialog.Owner = this;এটি প্যারেন্ট উইন্ডোর কেন্দ্রে অবস্থান করুন
একা

2

আপনি প্রয়োজন হবে না কোন এই অন্যান্য অভিনব উত্তর। নীচে একটি সরল উদাহরণ সব নেই যে Margin, Height, WidthXAML সেট বৈশিষ্ট্য, কিন্তু এই মৌলিক পর্যায়ে শেষ করার জন্য কিভাবে দেখানোর জন্য যথেষ্ট হওয়া উচিত।

এক্সএএমএল
একটি Windowপৃষ্ঠা তৈরি করুন যা আপনি সাধারণত পছন্দ করেন এবং এতে আপনার ক্ষেত্রগুলি যুক্ত করুন, বলুন Labelএবং এর মধ্যে একটি TextBoxনিয়ন্ত্রণ করুন StackPanel:

<StackPanel Orientation="Horizontal">
    <Label Name="lblUser" Content="User Name:" />
    <TextBox Name="txtUser" />
</StackPanel>

তারপরে Buttonসাবমিশনের জন্য একটি স্ট্যান্ডার্ড তৈরি করুন ("ঠিক আছে" বা "জমা দিন") এবং আপনি যদি চান তবে "বাতিল" বোতামটি তৈরি করুন:

<StackPanel Orientation="Horizontal">
    <Button Name="btnSubmit" Click="btnSubmit_Click" Content="Submit" />
    <Button Name="btnCancel" Click="btnCancel_Click" Content="Cancel" />
</StackPanel>

কোড-পিছনে
আপনি কোড-পিছনেClick ইভেন্ট হ্যান্ডলার ফাংশন যুক্ত করবেন, তবে আপনি যখন সেখানে যাবেন, প্রথমে একটি সর্বজনীন ভেরিয়েবল ঘোষণা করুন যেখানে আপনি আপনার পাঠ্যবাক্সের মানটি সংরক্ষণ করবেন:

public static string strUserName = String.Empty;

তারপরে, ইভেন্ট হ্যান্ডলার ফাংশনগুলির জন্য ( Clickএক্সএএমএল বোতামের ফাংশনটিতে ডান ক্লিক করুন , "যান সংজ্ঞাতে যান" নির্বাচন করুন এটি এটি আপনার জন্য তৈরি করবে), আপনার বাক্সটি খালি আছে কিনা তা দেখার জন্য আপনার একটি চেক দরকার। আপনি যদি এটি পরিবর্তনশীল না হয় তবে এটি সংরক্ষণ করুন এবং আপনার উইন্ডোটি বন্ধ করুন:

private void btnSubmit_Click(object sender, RoutedEventArgs e)
{        
    if (!String.IsNullOrEmpty(txtUser.Text))
    {
        strUserName = txtUser.Text;
        this.Close();
    }
    else
        MessageBox.Show("Must provide a user name in the textbox.");
}

অন্য পৃষ্ঠা থেকে এটিকে কল করা
আপনি ভাবছেন, আমি যদি আমার উইন্ডোটি this.Close()সেখানে দিয়ে বন্ধ করি তবে আমার মান চলে গেছে, তাই না? না !! আমি এটি অন্য সাইট থেকে খুঁজে পেয়েছি: http://www.dreamincode.net/forums/topic/359208-wpf-how-to-make-simple-popup-window-for-input/

কীভাবে আপনাকে Windowঅন্যের কাছ থেকে খুলতে হবে এবং মানগুলি পুনরুদ্ধার করতে হবে তার এটির (আমি এটি কিছুটা পরিষ্কার করেছি) এর অনুরূপ উদাহরণ ছিল :

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void btnOpenPopup_Click(object sender, RoutedEventArgs e)
    {
        MyPopupWindow popup = new MyPopupWindow();  // this is the class of your other page

        //ShowDialog means you can't focus the parent window, only the popup
        popup.ShowDialog(); //execution will block here in this method until the popup closes

        string result = popup.strUserName;
        UserNameTextBlock.Text = result;  // should show what was input on the other page
    }
}

বোতামটি বাতিল
আপনি ভাবছেন, তবে সেই বাতিল বোতামটির কী হবে, তবে? সুতরাং আমরা কেবল আমাদের পপ-আপ উইন্ডো কোড-পিছনে আরেকটি পাবলিক ভেরিয়েবল যুক্ত করব:

public static bool cancelled = false;

এবং আসুন আমাদের btnCancel_Clickইভেন্ট হ্যান্ডলারটি অন্তর্ভুক্ত করা যাক এবং এতে একটি পরিবর্তন আনুন btnSubmit_Click:

private void btnCancel_Click(object sender, RoutedEventArgs e)
{        
    cancelled = true;
    strUserName = String.Empty;
    this.Close();
}

private void btnSubmit_Click(object sender, RoutedEventArgs e)
{        
    if (!String.IsNullOrEmpty(txtUser.Text))
    {
        strUserName = txtUser.Text;
        cancelled = false;  // <-- I add this in here, just in case
        this.Close();
    }
    else
        MessageBox.Show("Must provide a user name in the textbox.");
}

এবং তারপরে আমরা আমাদের MainWindow btnOpenPopup_Clickইভেন্টে কেবল সেই পরিবর্তনশীলটি পড়ি :

private void btnOpenPopup_Click(object sender, RoutedEventArgs e)
{
    MyPopupWindow popup = new MyPopupWindow();  // this is the class of your other page
    //ShowDialog means you can't focus the parent window, only the popup
    popup.ShowDialog(); //execution will block here in this method until the popup closes

    // **Here we find out if we cancelled or not**
    if (popup.cancelled == true)
        return;
    else
    {
        string result = popup.strUserName;
        UserNameTextBlock.Text = result;  // should show what was input on the other page
    }
}

দীর্ঘ প্রতিক্রিয়া, তবে আমি এটি দেখতে চেয়েছিলাম যে এটি public staticভেরিয়েবলগুলি কীভাবে ব্যবহার করছে । না DialogResult, কোনও ফেরতের মান নেই, কিছুই নেই। কেবল উইন্ডোটি খুলুন, পপ-আপ উইন্ডোতে বোতামের ইভেন্টগুলি সহ আপনার মানগুলি সংরক্ষণ করুন, তারপরে মূল উইন্ডো ফাংশনে এগুলি পুনরুদ্ধার করুন।


প্রদত্ত কোডটি উন্নত করার অনেক উপায় রয়েছে: ১) ডেটা সংরক্ষণের জন্য স্ট্যাটিক ব্যবহার করবেন না, অন্যথায় আপনি মাঝে মধ্যে বেশ কয়েকটি ডায়ালগ নিয়ে সমস্যায় পড়বেন; 2) শোডায়ালগ () এর মাধ্যমে "সত্য" পাস করার জন্য ডায়ালগের ফলাফল রয়েছে; 3) আইসনসেল এট্রিবিউট একটি বাটনটির জন্য এটি কোনও অতিরিক্ত কোড ছাড়াই সত্য বাতিল বোতামে পরিণত করে ...
এন্টোনকে

@ অ্যান্টোনক ১) স্থির অবজেক্ট ব্যবহার করে আপনি কীভাবে সমস্ত ক্লাসে তাত্ক্ষণিকভাবে না রেখে অন্যান্য ক্লাসে ভেরিয়েবল কল করতে পারেন। আমার কাছে, স্ট্যাটিক ভেরিয়েবলগুলি সমস্ত কিছু কেটে দেয় এবং এটি আরও বেশি পছন্দনীয়। তাদের সাথে কখনই কোনও সমস্যা হয়নি, কারণ যে কোনও বস্তু (উইন্ডো, পৃষ্ঠা) খোলার পরে তারা পুনরায় সেট করবে। আপনি যদি বেশ কয়েকটি ডায়ালগ চান, তবে প্রত্যেকের জন্য একটি ডায়ালগ তৈরি করুন - বারবার একইরকম ব্যবহার করবেন না বা হ্যাঁ, এটি সমস্যাযুক্ত - তবে খারাপ কোডিংও, কারণ কেন আপনি একই বার্তাটি 50 বার চান?
vapcguy

@AntonK 2) আপনি ফিরে পাস করতে পারেন না DialogResultWPF, এটা এর MessageBoxResult, যা আমি খুঁজে পাওয়া যায় নি শুধুমাত্র একটি উপর মান বোতামগুলি থেকে কাজ করে MessageBox.Show()ডায়ালগ - এক একটি কাস্টম কথোপকথন থেকে মাধ্যমে দেখানো .ShowDialog()- এবং যা করতে পারেন শুধুমাত্র ক্যোয়ারী মান অপারেটার জন্য, MessageBoxResult.OK, MessageBoxResult.Cancel, "হ্যাঁ" , "না" ইত্যাদি - বুলিয়ান বা কাস্টম মানগুলি নয়। 3) IsCancelএটি কোনও বুলিয়ানে সঞ্চয় করে এবং যে কোনওভাবেই এটি প্রেরণ করা প্রয়োজন, সুতরাং এটি ছিল এক-আকারের-ফিটস-সমস্ত সমাধান।
vapcguy
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.