【问题标题】:wpf my UI doesnt refrashwpf我的用户界面不刷新
【发布时间】:2010-08-22 07:18:00
【问题描述】:

我的 xml 是:

<Window.Resources>
    <Style TargetType="ListViewItem">
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
    </Style>
</Window.Resources>


<Grid  >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="381*" />
        <ColumnDefinition Width="20*" />
        <ColumnDefinition Width="101*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="110*" />
        <RowDefinition Height="201*" />
    </Grid.RowDefinitions>
    <StackPanel Margin="320,0,0,0" Grid.RowSpan="2">
        <ListView ItemsSource="{Binding employeeCollection}">
            <ListView.View>
                <GridView>

                    <GridViewColumn Header="Employee ID" DisplayMemberBinding="{Binding Path=EmployeeID}"/>
                    <GridViewColumn Header="First Name" DisplayMemberBinding="{Binding Path=FirstName}"/>
                    <GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding Path=LastName}"/>
                    <GridViewColumn Header="start" DisplayMemberBinding="{Binding Path=startHR}"/>
                    <GridViewColumn Header="finish" DisplayMemberBinding="{Binding Path=finishHR}">

                </GridViewColumn>
            </GridView>
    </ListView.View>

        </ListView>
    </StackPanel>
            <StackPanel Margin="2,0,0,137" Grid.RowSpan="2" Grid.ColumnSpan="2" Grid.Column="1">
        <ListBox FontFamily="Guttman Yad-Brush" BorderBrush="AliceBlue" BorderThickness="5" ItemsSource="{Binding Path=dateItems}" DisplayMemberPath="Name" SelectedValuePath="Name" SelectedValue="{Binding Path=dateItem}" Width="233" Height="164" />
    </StackPanel>
    <Button Click="Button_Click" Width="102" Height="34" Margin="0,98,-1,69" Grid.Row="1" Grid.Column="2" Content="בחר" FontFamily="Guttman Yad-Brush" Background="AliceBlue"></Button>
    <TextBox Name="dateTextBox" Grid.Column="1" Margin="26,152,0,33" Grid.Row="1" FontFamily="Guttman Yad-Brush" Grid.ColumnSpan="2" />
    <Calendar SelectedDate="{Binding Path=SelectedDate}" Height="168" Name="calendar1" Width="182" SelectedDatesChanged="calendar1_SelectedDatesChanged" Margin="66,68,485,115" Grid.RowSpan="2" />
</Grid>

--> -->

这是开始窗口类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;
using System.Windows.Data;

using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;


namespace WpfApplication1
{

public partial class MainWindow : Window
{
    ConnectionViewModel vm;

    public MainWindow()
{
    InitializeComponent();
    vm = new ConnectionViewModel();

    DataContext = vm;
}
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        //((ConnectionViewModel)DataContext).dateItems = "test";
        if (vm.cm.dateItem.ToString() != null)
        {
            dateTextBox.Text = vm.cm.dateItem.ToString();
            vm.em.insert();
        }
    }

    private void calendar1_SelectedDatesChanged(object sender, SelectionChangedEventArgs e)
    {

            string []s = calendar1.SelectedDate.ToString().Split(' ');
            dateTextBox.Text = s[0];
    }

 }

public class ConnectionViewModel
{

    public DateConectionModule cm;
    public employeesGrid em;

    public ConnectionViewModel()
    {

        cm = new DateConectionModule();
        em = new employeesGrid();

    }

    public CollectionView dateItems
    {
        get { return cm.dateItems; }
    }
    public string dateItem
    {
        get {return cm.dateItem;} 
        set{ cm.dateItem = value;}
    }
    public CollectionView employeeCollection
    {
        get { return em.employeeCollection; }
    }



}




public class DateConectionModule : INotifyPropertyChanged
{

    public static string[] datesString = { "01.01.2011", "02.01.2011", "03.01.2011", "04.01.2011", "05.01.2011" };

    public DateConectionModule()
    {

        employeesGrid em = new employeesGrid();
        IList<dateItem> list = new List<dateItem>();
        //query to database should be here
        foreach (string dataString in datesString)
        {
            list.Add(new dateItem(dataString));
        }
        _dateItemList = new CollectionView(list);
    }
    private readonly CollectionView _dateItemList;
    private string m_dateItem;

    public CollectionView dateItems
    {
        get { return _dateItemList; }
    }

    public string dateItem
    {
        get { return m_dateItem; }
        set
        {
            if (m_dateItem == value)
                return;
            m_dateItem = value;
            OnPropertyChanged("dateItem");
        }
    }
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    public event PropertyChangedEventHandler PropertyChanged;
}





public class dateItem
{
    public string Name { get; set; }
    public dateItem(string name)
    {
        Name = name;
    }
}

public class employeesGrid : INotifyPropertyChanged
{
    private CollectionView _dateItemList;
    private string m_dateItem;


    public employeesGrid()
    {
        IList<employiesData> list = new List<employiesData>();
        //query to database should be here
        list.Add(new employiesData{
        EmployeeID =  "036854768",
        FirstName = "yoav" ,
        LastName = "stern",
        startHR = "1600" ,
        finishHR = "0200"});
        _dateItemList = new CollectionView(list);
    }

    public void insert()
    {
        IList<employiesData> list = new List<employiesData>();
        //query to database should be here
        list.Add(new employiesData
        {
            EmployeeID = "0234235345",
            FirstName = "shoki",
            LastName = "zikri",
            startHR = "1600",
            finishHR = "0200"
        });
        _dateItemList = new CollectionView(list);
        OnPropertyChanged("employeeCollection");
    }

    public CollectionView employeeCollection
    {
        get { return _dateItemList; }

        set
        {
            if (_dateItemList == value) 
                return;
            _dateItemList = value;
            OnPropertyChanged("employeeCollection");
        }
    }
    private void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    public event PropertyChangedEventHandler PropertyChanged;

}
public class employiesData
{
    public string EmployeeID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string startHR { get; set; }
    public string finishHR { get; set; }
}

}

1.我希望在调用 insertTest 时 UI 会加载我的新值

2.这是我的第一个 wpf 工作,所以任何关于如何使事情更易读、更有效、更简单的建议以及关于我糟糕的架构的注释我知道它很糟糕可以一些

【问题讨论】:

  • 提供更多细节。你如何在界面中绑定(?)这个集合?
  • @victor 我希望我所做的编辑对您有所帮助,而不是版本中的信息超载我只是想知道您是否对我糟糕的架构提出了更好的建议,这是我的第一个 wpf 应用程序和我需要建议。

标签: wpf wpf-controls binding


【解决方案1】:

低于我的观点

1- ConnectionViewModel 类有什么用,它只是扭曲 DataConnectionViewModel 所以我建议你可以摆脱 ConnectionViewModel() 并使用 DataConnectionViewModel。

2-我认为您可以摆脱 employeesGrid 类,因为您只需要一个员工集合,因此不要使用单独的集合类,而是在 DataConnectionViewModel() 类中创建一个 observrablecollection。

3- 使用 Wpf- Model -View-ViewModel 模板,这会给你更好的主意

4- 我刚刚重构了您的代码并创建了一个类似的应用程序,它使用 MVVM 和 ObservableCollection,并且使用起来更简单。

我的 xaml

<Window.Resources>
    <Style TargetType="ListViewItem">
        <Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
    </Style>
</Window.Resources>


<Grid  >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="381*" />
        <ColumnDefinition Width="20*" />
        <ColumnDefinition Width="101*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="110*" />
        <RowDefinition Height="201*" />
    </Grid.RowDefinitions>
    <StackPanel Margin="320,0,0,0" Grid.RowSpan="2">
        <ListView ItemsSource="{Binding EmpList}">
            <ListView.View>
                <GridView>

                    <GridViewColumn Header="Employee ID" DisplayMemberBinding="{Binding Path=EmployeeID}"/>
                    <GridViewColumn Header="First Name" DisplayMemberBinding="{Binding Path=FirstName}"/>
                    <GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding Path=LastName}"/>
                    <GridViewColumn Header="start" DisplayMemberBinding="{Binding Path=startHR}"/>
                    <GridViewColumn Header="finish" DisplayMemberBinding="{Binding Path=finishHR}">

                    </GridViewColumn>
                </GridView>
            </ListView.View>

        </ListView>
    </StackPanel>
    <StackPanel Margin="2,0,0,137" Grid.RowSpan="2" Grid.ColumnSpan="2" Grid.Column="1">
        <ListBox FontFamily="Guttman Yad-Brush" BorderBrush="AliceBlue" BorderThickness="5" ItemsSource="{Binding Path=dateItems}" DisplayMemberPath="Name" SelectedValuePath="Name" SelectedValue="{Binding Path=dateItem}" Width="233" Height="164" />
    </StackPanel>
    <!--<Button Click="Button_Click" Width="102" Height="34" Margin="0,98,-1,69" Grid.Row="1" Grid.Column="2" Content="בחר" FontFamily="Guttman Yad-Brush" Background="AliceBlue"></Button>-->
    <TextBox Name="dateTextBox" Grid.Column="1" Margin="26,152,0,33" Grid.Row="1" FontFamily="Guttman Yad-Brush" Grid.ColumnSpan="2" />
    <!--<Calendar SelectedDate="{Binding Path=SelectedDate}" Height="168" Name="calendar1" Width="182" SelectedDatesChanged="calendar1_SelectedDatesChanged" Margin="66,68,485,115" Grid.RowSpan="2" />-->
</Grid>

我的代码

1-

创建继承 ViewModelBase 类的 DataConnectionViewModel。

使用系统; 使用 System.Collections.Generic; 使用 System.Linq; 使用 System.Text; 使用 Employee.Models; 使用 System.Collections.ObjectModel;

命名空间 Employee.ViewModels { 公共类 DateConectionModule : ViewModelBase { #region "实例变量" 公共静态字符串 [] 日期字符串 = { "01.01.2011", "02.01.2011", "03.01.2011", "04.01.2011", "05.01.2011" }; #endregion "实例变量"

    #region " Constructor "

    public DateConectionModule()
    {
        CreateEmployeeData();
    }
    #endregion " Constructor "


    #region " Public Properties "

    public ObservableCollection<EmployeeData> EmpList { get; set; }



    #endregion " Public Properties "


    #region " Helper Methods "

    private void CreateEmployeeData()
    {
        EmpList = new ObservableCollection<EmployeeData>();
        EmpList.Add
            (
             new EmployeeData() {  EmployeeID="1", LastName="Gates", FirstName="Bill", finishHR="", startHR =""  }
            );

    }

    #endregion " Helper Methods "




} 

}

2- ViewModelBAse 类

使用系统; 使用 System.Collections.Generic; 使用 System.ComponentModel; 使用 System.Linq; 使用 System.Text; 使用 System.Windows; 使用 System.Windows.Input;

命名空间 Employee.ViewModels { /// /// 为 ViewModel 类提供通用功能 /// 公共抽象类 ViewModelBase : INotifyPropertyChanged { 公共事件 PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

}

}

3- 在 MainWindow.Xaml.cs 中设置数据上下文

公共部分类 MainView : Window { 公共主视图() { 初始化组件();

        this.DataContext = new DateConectionModule();
    }
}

还有很多其他的东西,比如依赖注入等。但是对于你的情况,你可以编写一个控制器来调用你的数据服务来给你员工列表而不是分配列表给 observablecollection。

4- 我可以建议阅读 abot Prism 框架,它在应用程序管理和 TDD 中为您提供了极大的灵活性。

【讨论】:

  • 是的,我认为关键在于设计本身,我只是不知道如何去做,如果你能推荐一篇给出示例的文章,我会非常高兴..
猜你喜欢
  • 2021-08-19
  • 2014-12-10
  • 2011-01-08
  • 1970-01-01
  • 2016-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多