簡體   English   中英

UserControl屬性綁定不更新DataContext

[英]UserControl Property Binding not Updating the DataContext

我創建了這個簡單的可重用控件來瀏覽文件。

然后我做了一個模型並實現了OnPropertyChanged並在MainWindow中使用了該控件。

當我單擊UserControl中的“瀏覽”按鈕時,DependencyProperty“FilePath”被正確設置(並且文本框獲取路徑字符串)但模型似乎不起作用。

附加信息:如果我使用普通文本框而不是UserControl廣告

<TextBox Text="{Binding InputFile}"/>

當我在框中輸入內容時,模型會正確更新。 如果我在UserControl中手動輸入內容(而不是通過“瀏覽”按鈕填充它,它無論如何都不起作用)

這是UserControl的代碼,該屬性在控件中正確設置:

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

    // FilePath
    public static readonly DependencyProperty FilePathProperty =
        DependencyProperty.Register("FilePath", typeof(string), typeof(FileBrowserTextBox), new FrameworkPropertyMetadata(string.Empty, new PropertyChangedCallback(OnFilePathPropertyChanged)));

    public string FilePath
    {
        get { return (string)GetValue(FilePathProperty); }
        set { SetValue(FilePathProperty, value); }
    }
    static void OnFilePathPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        var obj = o as FileBrowserTextBox;
        if (obj == null)
            return;
    }
    private void BrowseButton_Click(object sender, RoutedEventArgs e)
    {
        // Create OpenFileDialog 
        Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
        // Set filter for file extension and default file extension 
        dlg.DefaultExt = ".txt";
        dlg.Filter = "TXT Files (*.txt)|*.txt|All Files (*.*)|*.*";
        // Display OpenFileDialog by calling ShowDialog method 
        Nullable<bool> result = dlg.ShowDialog();
        // Get the selected file name and display in a TextBox 
        if (result == true)
        {
            // Open document 
            string filename = dlg.FileName;
            FilePath = filename; // this works and updates the textbox
        }
    }
}

這是XAML的摘錄:

<UserControl x:Class="DrumMapConverter.FileBrowserTextBox">
        ...
        <Button Content=" ... " Click="BrowseButton_Click"/>
        <TextBox Name="txtFilepath" Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=FilePath}"/>
        ...
</UserControl>

這是我與INotifyPropertyChanged一起使用的模型:

public class DrumMapConverterDataModel :INotifyPropertyChanged
{
    public string InputFile
    {
        get { return inputFile; }
        set
        {
            inputFile = value;
            OnPropertyChanged("InputFile");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    // Create the OnPropertyChanged method to raise the event 
    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }

    private string inputFile;
}

這是MainWindow類

public partial class MainWindow : Window
{
    private DrumMapConverterDataModel model;
    public MainWindow()
    {
        InitializeComponent();
        model = new DrumMapConverterDataModel();
        DataContext = model;
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        MessageBox.Show(model.InputFile); // if i break here the model has no data changed (InputFile is null)
    }
}

這是我如何使用2個控件(2個例子,它們都不起作用):

<cust:FileBrowserTextBox  Label="Input File" FilePath="{Binding InputFile}"/>
<cust:FileBrowserTextBox  Label="Input File" FilePath="{Binding Path=InputFile, Mode=TwoWay, 
                       RelativeSource={RelativeSource FindAncestor, 
                           AncestorType=Window}}"/>

任何幫助將非常感激。

更新和解決方案:

正如@AnatoliyNikolaev(感謝他對UpdareSourceTrigger的解釋)和用戶控件中的@Karuppasamy的建議,可以這樣做(明確使用UpdateSourceTrigger,因為它是一個文本框):

<TextBox Grid.Column="2" Name="txtFilepath" Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=FilePath, UpdateSourceTrigger=PropertyChanged}"/>

然后DependencyProperty可以是這樣的(注意BindsTwoWayByDefault ):

public static readonly DependencyProperty FilePathProperty =
    DependencyProperty.Register("FilePath", typeof(string), typeof(FileBrowserTextBox), new FrameworkPropertyMetadata(string.Empty, new PropertyChangedCallback(OnFilePathPropertyChanged)) { BindsTwoWayByDefault = true });

所以最后在MainWindow我可以簡單地寫這個:

<cust:FileBrowserTextBox  FilePath="{Binding Path=InputFile}" />

嘗試將依賴項屬性設置UpdateSourceTrigger設置為PropertyChanged

默認值為Default ,它返回目標依賴項屬性的默認UpdateSourceTrigger值。 但是,大多數依賴項屬性的默認值是PropertyChanged ,而Text屬性的默認值是LostFocus

例:

<local:FileBrowserTextBox FilePath="{Binding Path=InputFile, 
                                             Mode=TwoWay,
                                             UpdateSourceTrigger=PropertyChanged}" />

希望我理解你的問題,

我嘗試過相同的操作,並在將UserControl的XAML代碼中的TextBox綁定時將UpdateSourceTrigger設置為PropertyChanged。 以下是我的代碼,

 <TextBox Width="200" Name="txtFilepath" Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=FilePath, UpdateSourceTrigger=PropertyChanged}"/>
    <Button Width="40" Content=" ... " Click="BrowseButton_Click"/>

它正在發揮作用。

謝謝

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM