【问题标题】:How do I check on the properties of WPF elements whilst in a different class?如何在不同的类中检查 WPF 元素的属性?
【发布时间】:2015-03-06 13:57:55
【问题描述】:

我正在关注一堆不同的示例等,并尝试用它做我自己的事情。

基本上,在我的代码后面,我有一个单独的类。我认为这是用于 MVVM 的,虽然我几乎不知道那是什么意思(我明白这一点,但它看起来令人困惑!)。

无论如何...这是我的 WPF 表单背后代码的单独类(相同命名空间)中的代码:

public class ChartViewModel
    {
        public ChartViewModel()
        {
            DataTable dataNames = new DataTable();
            try
            {
                var db = new SQLiteDatabase();
                string query = "SELECT DISTINCT Name FROM Main";
                ...

现在,我的 WPF xaml 页面上有一个名为 AccountType 的文本块。其中的文本可以在三个不同的值之间循环,我需要基于此更改上面代码块末尾的字符串查询。如果是一个值,则字符串 = x。如果它是第二个值,则 string = y 等...

该类的部分用于使用来自数据库的条目填充组合框。更改该字符串然后会自动强制组合框更新吗?或者在此之后我还需要做其他事情吗?

根据要求,这是我的 XAML(反正相关的东西)

<ComboBox x:Name="NameBox" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center" ItemsSource="{Binding Names}" Width="100" />
<Grid Grid.Row="0" Grid.Column="1">
    <ProgressBar x:Name="AccountTypeProgress" Width="70" Height="20" MouseDown="AccountTypeButton_Click" />
    <TextBlock x:Name="AccountType" Text="Main" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="#FF252525" FontSize="16" FontWeight="Bold" MouseDown="AccountTypeButton_Click" />
</Grid>

完整视图模型

public class ChartViewModel
{
    public ChartViewModel()
    {
        AccountType = "Main";

        DataTable dataNames = new DataTable();
        try
        {
            var db = new SQLiteDatabase();
            string query = "SELECT DISTINCT Name FROM Main";

            dataNames = db.GetDataTable(query);
        }
        catch (Exception fail)
        {
            string error = "The following error has occured:\n\n";
            //error += fail.Message.ToString() + "\n\n";
            //System.Windows.MessageBox.Show(error);
        }

        this.Names = new ObservableCollection<string> { };

        foreach (DataRow row in dataNames.Rows)
        {
            string name = row["Name"].ToString();
            Names.Add(name);
        }


        int x = 42067;

        DataTable datastats = new DataTable();
        try
        {
            var db = new SQLiteDatabase();
            String query = "SELECT * FROM Main WHERE Name = \"9n\"";
            datastats = db.GetDataTable(query);
        }
        catch (Exception fail)
        {
            String error = "The following error has occurred:\n\n";
            //error += fail.Message.ToString() + "\n\n";
            //System.Windows.MessageBox.Show(error);
        }

        this.overall = new List<DataPoint>
        {
            //foreach(DataRow row in datastats.Rows)
            //{

            //}
        };

        foreach (DataRow row in datastats.Rows)
        {
            DateTime sDate = DateTime.Parse(row["Date"].ToString());
            //int date = ((sDate.Year - 1900)) + sDate.Day;
            sDate = sDate.Date;
            double date = sDate.ToOADate() - 1;
            int dateint = Convert.ToInt32(date);

            string sLevel = row["OverallL"].ToString();
            int level = Convert.ToInt32(sLevel);

            this.overall.Add(new DataPoint(date, level));

        }

        this.overall.Add(new DataPoint(42100, 10));
        this.overall.Add(new DataPoint(42110, 10));

        this.Title2 = "Example 2";
        this.Points = new List<DataPoint>
            {
                new DataPoint(x, 4),
                new DataPoint(42077, 13),
                new DataPoint(42087, 15),
                new DataPoint(42097, 16),
                new DataPoint(42107, 12),
                new DataPoint(42117, 12)
            };
        this.Data = new List<DataPoint>
            {
                new DataPoint(42067, 10),
                new DataPoint(42077, 15),
                new DataPoint(42087, 16),
                new DataPoint(42097, 20),
                new DataPoint(42107, 10),
                new DataPoint(42117, 12)
            };
    }


    public string Title2 { get; private set; }

    public IList<DataPoint> Points { get; private set; }
    public IList<DataPoint> Data { get; private set; }
    public IList<DataPoint> overall { get; private set; }

    public ObservableCollection<string> Names { get; private set; }

    private string _AccountType;

    public string AccountType
    {
        get { return _AccountType; }
        set
        {
            _AccountType = value;

            //OnPropertyChanged stuff here.
        }
    }

}

【问题讨论】:

  • 你能提供一些 XAML 吗?您是否将文本绑定到任何东西?
  • 我已经在 OP 中添加了相关的 XAML。 :) 单击进度库或文本块是使文本块值在三个值之间循环的原因,这就是附加到这些值的所有方法。
  • 添加“名称”属性代码。如果这是一个简单的列表,您需要将其转换为 observablecollection。完整的viewmodel代码会更有帮助回答
  • 现在添加了所有视图模型代码。 :)

标签: c# wpf xaml mvvm


【解决方案1】:

首先,在您的 ViewModel 中,您可以为 AccountType 文本块创建一个属性以绑定到:

private string _AccountType;

    public string AccountType
    {
        get { return _AccountType; }
        set 
        { 
            _AccountType = value; 

            //OnPropertyChanged stuff here.
        }
    }

当您循环帐户类型时,更新此属性,它也会更新 UI。

您首先需要在 TextBlock 上设置绑定:

<TextBlock Text="{Binding AccountType}" ... />

然后您可以简单地在查询中使用此属性。

该类的部分用于使用来自数据库的条目填充组合框。更改该字符串然后会自动强制组合框更新吗?或者在此之后我还需要做其他事情吗?

对从 UI 绑定到的列表使用 ObservableCollection 是一种很好的做法。如果您还没有使用它,那么请这样做,因为它会为您处理属性更改的内容,并且会在从列表中添加/删除项目时更新绑定。

如果我遗漏了什么,请告诉我。

【讨论】:

  • 看起来不错,但我仍然无法掌握一件事 - 我想循环值 onclick 进度条或文本块... onclick 方法位于我页面的主命名空间中,但视图模型是不同的命名空间。我似乎无法引用他们之间的任何内容...我该怎么做?
  • 在这种情况下,您应该使用 ICommand 循环这些值。您的 ICommand 应该是 ViewModel 中的一个属性,并且您的 TextBlock 可以通过 InputBindings 绑定到它。这是一个在单个评论中解释的大话题,但这里有一个教程 on using ICommandinput bindings 上的另一个教程。请注意,第二个链接没有详细介绍,但您要查找的是 MouseBinding,而不是 KeyBinding。
  • 即使有所有有用的链接,我仍然无法解决这个问题。 :( 我已经用我的视图模型代码更新了主帖子...我的组合框填充了主数据库表中的数据(使用 SQL 查询设置)。但是,我需要两件事。我不知道如何循环文本框 onclick 使用 accountname 字符串...此外,我需要根据文本块的值设置从名称填充组合框的查询字符串。谢谢
猜你喜欢
  • 2021-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 2015-12-19
  • 2018-11-04
  • 2011-10-25
  • 2019-04-30
相关资源
最近更新 更多