简体   繁体   English

将单个控件绑定到视图模型属性

[英]Binding A Single Control to a View Model Property

I'm attempting to bind the text of a TextBlock control as shown: 我试图绑定一个TextBlock控件的文本,如下所示:

<TextBlock DataContext="ProgressViewModel" Text="{Binding FileName}" HorizontalAlignment="Center"/>

"ProgressViewModel" is a class that exists in my project and exposes the FileName property: “ ProgressViewModel”是我的项目中存在的一个类,它公开FileName属性:

    private string _fileName;
    public string FileName
    {
        get { return _fileName; }
        set { this.MutateVerbose(ref _fileName, value, RaisePropertyChanged()); }
    }

I know that FileName is being updated correctly as I can watch its value in the debuggger. 我知道FileName正在正确更新,因为我可以在debuggger中观察它的值。 However, I can't get the XAML binding to work. 但是,我无法使XAML绑定正常工作。 I'm trying to avoid setting a master binding in the Window.Resources as some articles have suggested since I have multiple view models in this project. 我试图避免在Window.Resources中设置主绑定,因为一些文章建议使用该资源,因为我在该项目中有多个视图模型。

Full view model: 全视图模型:

using MaterialDesignThemes.Wpf;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;

namespace MaterialDesignTest

{
    public class ProgressViewModel : INotifyPropertyChanged
    {

    System.Windows.Forms.Timer progressTimer;

    private double _saveProgressButton;
    public double SaveProgressButton
    {
        get { return _saveProgressButton; }
        set { this.MutateVerbose(ref _saveProgressButton, value, RaisePropertyChanged()); }
    }
    private string _fileName;
    public string FileName
    {
        get { return _fileName; }
        set { this.MutateVerbose(ref _fileName, value, RaisePropertyChanged()); }
    }

    private bool _isSaveComplete;
    public bool IsSaveComplete
    {
        get { return _isSaveComplete; }
        private set { this.MutateVerbose(ref _isSaveComplete, value, RaisePropertyChanged()); }
    }

    private bool _isSaving;
    public bool IsSaving
    {
        get { return _isSaving; }
        private set { this.MutateVerbose(ref _isSaving, value, RaisePropertyChanged()); }
    }

    int progress = 0;
    int cycles = 0;
    public ProgressViewModel()
    {

    }
    public void KickOffProgressTimer()
    {
        progressTimer = new System.Windows.Forms.Timer();
        progressTimer.Tick += new EventHandler(progressTimerTick);
        progressTimer.Interval = 40;
        progressTimer.Start();
    }

    private async void progressTimerTick(object sender, EventArgs e)
    {
        FileName = SelectRandomString();

        if (progress < 100 && cycles < 2)
        {
            if (progress == 99)
            {
                cycles++;
                progress = 0;
            }

            IsSaveComplete = false;
            IsSaving = true;
            progress++;
            SaveProgressButton = progress;
        }
        else
        {
            IsSaveComplete = true;
            IsSaving = false;
            progressTimer.Enabled = false;
            SaveProgressButton = 0;

            await NonBlockingDelay(1750);

            DialogHost.CloseDialogCommand.Execute(null, null);
        }
    }
    async Task NonBlockingDelay(int value)
    {
        await Task.Delay(value);
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private Action<PropertyChangedEventArgs> RaisePropertyChanged()
    {
        return args => PropertyChanged?.Invoke(this, args);
    }

    static string SelectRandomString()
    {
        var random = new Random();
        var questions = new List<string>{
            @"C:\Files\Filename1",
            @"C:\Filename2",
            @"C:\Filename3",
            @"C:\Filename4",
            @"C:\Temp\Files\Filename5",
            @"C:\Filename6",
            @"C:\Demo\LongFolderName\Filename7",
            @"C:\Filename8",
            @"C:\Filename9",
        };
        int index = random.Next(questions.Count);
        return(questions[index]);
    }
}

}

It's not working because you're currently binding to string value "ProgressViewModel" ; 它不起作用,因为您当前正在绑定到字符串值"ProgressViewModel" ; instead, you should bind to an instance to an object of type ProgressViewModel . 相反,您应该将实例绑定到类型为ProgressViewModel的对象。 Try: 尝试:

<TextBlock Text="{Binding FileName}" HorizontalAlignment="Center">
    <TextBlock.DataContext>
        <ns:ProgressViewModel />
    </TextBlock.DataContext>
</TextBlock>

Here, I assume you defined the namespace that contains ProgressViewModel as an XML namespace ns in the root tag. 在这里,我假设您已将包含ProgressViewModel的名称空间定义为根标记中的XML名称空间ns I also assume that ProgressViewModel has a public parameterless constructor. 我还假设ProgressViewModel具有公共的无参数构造函数。

The following is how you define ns . 以下是定义ns If ProgressViewModel is defined in namespace WpfApp1 , ns should be written like this: xmlns:ns="clr-namespace:WpfApp1" 如果ProgressViewModel在命名空间中定义WpfApp1ns应该这样写: xmlns:ns="clr-namespace:WpfApp1"

namespace WpfApp1
{
    public class ProgressViewModel
    {
    //...
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM