MV-VM 模式中使用 WPF 的 OpenFileDialog

发布于 2024-11-30 01:20:52 字数 122 浏览 1 评论 0原文

我需要使用 OpenFileDialog 来选择文件,但我无法使用任何以 MVVM 为中心的工具包(例如 Galgasoft),这些工具包允许我在不违反 MVVM 模式的情况下执行此操作。

我还能怎样实现这一目标?

I need to use the OpenFileDialog to select a file, but I can't use any of the MVVM-centric toolkits like Galgasoft that allow me to do this without violating the MVVM pattern.

How else can I achieve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

筱武穆 2024-12-07 01:20:52

当然,这是我用来读取 Excel 文件的一些代码的示例。它进入 ViewModel 并从 SelectFileCommand 调用。

private void SelectFile()
{
    var dlg = new OpenFileDialog();
    dlg.DefaultExt = ".xls|.xlsx";
    dlg.Filter = "Excel documents (*.xls, *.xlsx)|*.xls;*.xlsx";

    if (dlg.ShowDialog() == true)
    {
        var file = new FileInfo(dlg.FileName);
        ReadExcelFile(file.FullName);
    }
}

private void ReadExcelFile(fileName)
{
    try
    {
        using (var conn = new OleDbConnection(string.Format(@"Provider=Microsoft.Ace.OLEDB.12.0;Data Source={0};Extended Properties=Excel 8.0", fileName)))
        {
            OleDbDataAdapter da = new OleDbDataAdapter("SELECT DISTINCT [File Number] FROM [Sheet1$]", conn);
            var dt = new DataTable();
            da.Fill(dt);

            int i;
            FileContents = (from row in dt.AsEnumerable()
                            where int.TryParse(row[0].ToString(), out i)
                            select row[0]).ToList()
                            .ConvertAll<int>(p => int.Parse(p.ToString()));
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Unable to read contents:\n\n" + ex.Message, "Error");
    }
}

您需要为 OpenFileDialog 引用 Microsoft.Win32

Sure, here's an example of some code I use to read Excel files. It goes in a ViewModel and gets called from a SelectFileCommand

private void SelectFile()
{
    var dlg = new OpenFileDialog();
    dlg.DefaultExt = ".xls|.xlsx";
    dlg.Filter = "Excel documents (*.xls, *.xlsx)|*.xls;*.xlsx";

    if (dlg.ShowDialog() == true)
    {
        var file = new FileInfo(dlg.FileName);
        ReadExcelFile(file.FullName);
    }
}

private void ReadExcelFile(fileName)
{
    try
    {
        using (var conn = new OleDbConnection(string.Format(@"Provider=Microsoft.Ace.OLEDB.12.0;Data Source={0};Extended Properties=Excel 8.0", fileName)))
        {
            OleDbDataAdapter da = new OleDbDataAdapter("SELECT DISTINCT [File Number] FROM [Sheet1$]", conn);
            var dt = new DataTable();
            da.Fill(dt);

            int i;
            FileContents = (from row in dt.AsEnumerable()
                            where int.TryParse(row[0].ToString(), out i)
                            select row[0]).ToList()
                            .ConvertAll<int>(p => int.Parse(p.ToString()));
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Unable to read contents:\n\n" + ex.Message, "Error");
    }
}

You need to reference Microsoft.Win32 for the OpenFileDialog

花心好男孩 2024-12-07 01:20:52

您可以创建一个自定义控件,这样您只需将其中的字符串绑定到您的 viewmodel 属性即可。

我通常创建的自定义控件由以下内容组成:

  • 文本框或文本
  • 块 带有图像作为模板的按钮
  • 字符串依赖属性,其中文件路径将被包装到

所示

<Grid>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>

    <TextBox Grid.Column="0" Text="{Binding Text, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
    <Button Grid.Column="1"
            Click="Button_Click">
        <Button.Template>
            <ControlTemplate>
                <Image Grid.Column="1" Source="../Images/carpeta.png"/>
            </ControlTemplate>                
        </Button.Template>
    </Button>

</Grid>

和 *.cs 文件:

    public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
        "Text",
        typeof(string),
        typeof(customFilePicker),
        new FrameworkPropertyMetadata(
            null,
            FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Journal));

    public string Text
    {
        get
        {
            return this.GetValue(TextProperty) as String;
        }
        set
        {
            this.SetValue(TextProperty, value);
        }
    }

    public FilePicker()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        OpenFileDialog openFileDialog = new OpenFileDialog();

        if(openFileDialog.ShowDialog() == true)
        {
            this.Text = openFileDialog.FileName;
        }
    }

因此 *.xaml 文件将如下 您可以将其绑定到您的视图模型:

<controls:customFilePicker Text="{Binding Text}"}/>

You can create a custom control, so you can just bind a string from it to your viewmodel property.

The custom control I usually create is composed from:

  • Textbox or textblock
  • Button with an image as template
  • String dependency property where the file path will be wrapped to

So the *.xaml file would be like this

<Grid>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>

    <TextBox Grid.Column="0" Text="{Binding Text, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
    <Button Grid.Column="1"
            Click="Button_Click">
        <Button.Template>
            <ControlTemplate>
                <Image Grid.Column="1" Source="../Images/carpeta.png"/>
            </ControlTemplate>                
        </Button.Template>
    </Button>

</Grid>

And the *.cs file:

    public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
        "Text",
        typeof(string),
        typeof(customFilePicker),
        new FrameworkPropertyMetadata(
            null,
            FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Journal));

    public string Text
    {
        get
        {
            return this.GetValue(TextProperty) as String;
        }
        set
        {
            this.SetValue(TextProperty, value);
        }
    }

    public FilePicker()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        OpenFileDialog openFileDialog = new OpenFileDialog();

        if(openFileDialog.ShowDialog() == true)
        {
            this.Text = openFileDialog.FileName;
        }
    }

At the end you can bind it to your view model:

<controls:customFilePicker Text="{Binding Text}"}/>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文